Oracle fonctionne sous Solaris et le shell est par défaut csh. Ainsi, le script de connexion définit également Oracle_home, Oracle_sid dans csh. Mais je n'aime pas csh et veux utiliser bash pour faire mon travail. Alors, comment se procurer le script de connexion csh dans bash?
par exemple, voici ce que contient le fichier .cshrc. Et quand utiliser bash, j'aimerais utiliser ces variables. Une solution consiste à copier les variables à nouveau et à utiliser la commande bash, telle que export Oracle_SID = TEST. Mais cela nous obligera à conserver deux copies des fichiers. Et lorsque nous changeons le nom de la base de données ou mettons à niveau la base de données, je dois gérer le fichier de connexion bash séparément. C'est bien d'utiliser quelque chose comme
source .cshr dans bash, mais cela ne fonctionne pas.
setenv Oracle_SID TEST setenv Oracle_HOME /Oracle/TEST/home/products/10204[.____.unsetsetenv EPC_DISABLED TRUE setenv MANPATH/usr/local/man:/usr/share/man setenv EDITOR vi setenv LD_LIBRARY_PATH $ Oracle_HOME/lib:/usr/sfw/lib/64 setenv NLS_LANG AMERICAN_AMERICA.UTF8 setenv NLS_DATE_FORMAT -MON-RR "
Dans votre ~/.bashrc
(ou le premier de ~/.bash_profile
, ~/.bash_login
et ~/.profile
qui existe), sourcez ce script en utilisant quelque chose comme . ~/bin/sourcecsh
:
#!/bin/bash
# This should be sourced rather than executed
while read cmd var val
do
if [[ $cmd == "setenv" ]]
then
eval "export $var=$val"
fi
done < ~/.cshrc
Cette version élimine le mal eval
:
#!/bin/bash
# This should be sourced rather than executed
# yes, it will be sourcing within sourcing - what so(u)rcery!
source /dev/stdin < \
<(
while read cmd var val
do
if [[ $cmd == "setenv" ]]
then
echo "export $var=$val"
fi
done < cshrc
)
Modifier:
Sans sourcing stdin:
while read cmd var val
do
if [[ $cmd == "setenv" ]]
then
declare -x "$var=$val"
fi
done < cshrc
Je suis dans le meme bateau. Un collègue m'a montré ce qui suit:
Commencez à partir de rien, sans rien dans l'environnement:
bash> echo $$
12632
bash> echo $FOO
Voici le fichier csh qui obtient le source:
bash> cat setup-env.csh
setenv FOO "some csh stuff"
echo FOO=$FOO in csh
Voici la commande:
bash> csh -c 'source setup-env.csh;exec bash'
Regardez la sortie de csh
FOO=some csh stuff in csh
Et regardez le résultat du nouveau shell bash
bash> echo $$
13487
bash> echo $FOO
some csh stuff
Maintenant, partez et revenez à la bash Shell originale
bash> exit
exit
bash> echo $$
12632
bash>
Notez echo $$ pour voir les ID de processus, afin que nous puissions voir qu’ils sont différents processus Shell.
Mon collègue l'utilise assez pour le mettre dans un alias, comme:
# make csh environment scripts useable (sourceable) from bash function
# from Phil McCoy, Wed Nov 9 2011
source_csh () {
exec csh -c " source $*; setenv ALREADY_SOURCED \"$ALREADY_SOURCED:$*:\"; exec bash"
}
# sounds like a great idea to do source_csh .cshrc or .login
# but naively done is infinitely recursive,
# since the exec'ed bash will run .bashrc
Malheureusement, j'ai constaté que j'avais souvent besoin non seulement d'une configuration de variable d'environnement, mais également d'une configuration d'alias, comme dans le package de modules http://modules.sourceforge.net/ .
J'ai été en mesure d'automatiser cette "recette de script source csh" à l'aide de Perl Expect. Mais je n'ai pas pu être aussi interactif que je le souhaiterais, à l'exception de ce qui précède.
Dans votre bash .profile
, vous pouvez effectuer les opérations suivantes:
cat .cshrc | sed 's/setenv\s+(\S+)\s+(.*)$/set $1=$2; export $1/' > $HOME/.env_from_csh
source $HOME/.env_from_csh
Pourquoi ne pas définir une fonction appelée setenv, comme si
setenv() {
echo setting $1 to $2
export $1=$2
}
puis en recherchant le fichier .cshrc.
Quand je fais cela à bash, je reçois
[dws@oxygen ual-read-only]$ source cshrc
setting Oracle_SID to TEST
setting Oracle_HOME to /Oracle/TEST/home/products/10204
setting EPC_DISABLED to TRUE
setting MANPATH to /usr/local/man:/usr/share/man
setting EDITOR to vi
setting LD_LIBRARY_PATH to /Oracle/TEST/home/products/10204/lib:/usr/sfw/lib/64
setting NLS_LANG to AMERICAN_AMERICA.UTF8
setting NLS_DATE_FORMAT to DD-MON-RR
[dws@oxygen ual-read-only]$ env | grep Oracle
ORACLE_SID=TEST
Oracle_HOME=/Oracle/TEST/home/products/10204
La seule façon dont je puisse penser que ce serait de charger csh puis d’appeler bash à partir de ce nouveau shell. De cette façon, csh pourrait analyser ce fichier, puis la bash qu'elle engendrerait hériterait également de cet environnement.
Il existe un module par lequel vous pouvez créer le même fichier où que vous soyez dans un script Perl. Et vous obtiendrez tous les chemins d’environnement disponibles dans votre fichier csh.
Source::Shell
Passez par une petite documentation pour son utilisation.
Pour quelque chose d'aussi petit, il est courant de gérer deux scripts d'installation, l'un pour sh et ses dérivés, les shells, et l'autre pour csh et tcsh. Comme vous l'avez dit, cela crée un risque de désynchronisation des deux scripts - sauf si vous générez l'un à partir de l'autre, ou les deux à partir d'une source commune.
Cela impose une charge au responsable du ou des scripts d'installation plutôt qu'à chaque utilisateur qui doit les utiliser.