Как создать csh script в bash, чтобы установить среду
У нас есть Oracle, работающий на Solaris, а оболочка по умолчанию - csh. Таким образом, логин script устанавливает oracle_home, oracle_sid в csh. Но мне не нравится csh и я хочу использовать bash для выполнения моей работы. Итак, как установить csh login script в bash?
например, следующее в файле .cshrc. И при использовании bash, я бы хотел использовать эти переменные. Один из способов - скопировать переменные снова и использовать команду bash, такую как экспорт ORACLE_SID = TEST. Но для этого потребуется, чтобы мы сохранили две копии файлов. И когда мы меняем имя базы данных или обновляем базу данных, мне нужно поддерживать файл входа bash отдельно. Приятно просто использовать что-то вроде
source.cshr в bash, но он не работает.
setenv ORACLE_SID TEST
setenv ORACLE_HOME /oracle/TEST/home/products/10204
setenv 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 "DD-MON-RR"
Ответы
Ответ 1
В вашем ~/.bashrc
(или первом из ~/.bash_profile
, ~/.bash_login
и ~/.profile
, который существует) введите этот script, используя что-то вроде . ~/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
Эта версия устраняет зло 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
)
Edit:
Без поиска stdin:
while read cmd var val
do
if [[ $cmd == "setenv" ]]
then
declare -x "$var=$val"
fi
done < cshrc
Ответ 2
Я в одной лодке. Сотрудник показал мне следующее:
Начните с bash без использования в среде:
bash> echo $$
12632
bash> echo $FOO
Здесь csh файл, который получает source'd:
bash> cat setup-env.csh
setenv FOO "some csh stuff"
echo FOO=$FOO in csh
Здесь команда:
bash> csh -c 'source setup-env.csh;exec bash'
Посмотрите на вывод csh
FOO=some csh stuff in csh
И посмотрите на результат новой оболочки bash
bash> echo $$
13487
bash> echo $FOO
some csh stuff
Теперь оставьте и вернитесь к исходной оболочке bash
bash> exit
exit
bash> echo $$
12632
bash>
Обратите внимание на echo $$, чтобы увидеть идентификаторы процессов, чтобы мы могли видеть, что они являются разными процессами оболочки.
Моя коллега использует это достаточно, чтобы помещать его в псевдоним, например:
# 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
К сожалению, я обнаружил, что мне часто требуется не только настройка переменных среды, но и настройка псевдонимов, как в пакете модулей http://modules.sourceforge.net/.
Мне удалось автоматизировать этот "csh source script recipes", используя Perl Expect. Но я не мог быть таким интерактивным, как хотелось бы, кроме вышеупомянутого.
Ответ 3
В bash .profile
вы можете сделать следующее:
cat .cshrc | sed 's/setenv\s+(\S+)\s+(.*)$/set $1=$2; export $1/' > $HOME/.env_from_csh
source $HOME/.env_from_csh
Ответ 4
Как просто определить функцию, называемую setenv, например
setenv() {
echo setting $1 to $2
export $1=$2
}
а затем поиск файла .cshrc.
Когда я делаю это в bash, я получаю
[[email protected] 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
[[email protected] ual-read-only]$ env | grep ORACLE
ORACLE_SID=TEST
ORACLE_HOME=/oracle/TEST/home/products/10204
Ответ 5
Единственный способ, который я могу сделать, это загрузить csh, а затем вызвать bash из этой новой оболочки. Таким образом, csh может анализировать этот файл, а затем bash, который он порождает, наследует и эту среду.
Ответ 6
Для чего-то маленького, обычно используется два сценария установки: один для sh и sh-производных, shells и один для csh и tcsh. Как вы заметили, это создает риск того, что два сценария не синхронизируются - если вы не генерируете один из другого или не генерируете оба из общего источника.
Это накладывает нагрузку на поддерживающего устройства script (s), а не на каждого пользователя, который должен их использовать.
Ответ 7
Имеется доступный модуль, с помощью которого вы можете указать тот же файл, где хотите, в perl script. И вы получите все пути среды, доступные в вашем файле csh.
Source::Shell
Пройдите небольшую документацию для ее использования.
Ответ 8
Просто наличие "#!/bin/tcsh
" или аналогичного оператора, доступного в начале CSH script в связи с созданием исполняемого файла script, решило проблему для меня. В этом случае я мог бы напрямую вызвать CSH script из bash.
В качестве примера мне пришлось запустить tools.csh из bash script, называемого setup.sh. Я сделал что-то вроде этого в bash script:
if [ -z \`head -1 tools.csh | grep '^#!'\` ];
then
TCSH=\`which tcsh\`;
echo "'#!'$TCSH" > tools.csh.temp;
cat tools.csh >> tools.csh.temp;
mv tools.csh.temp tools.csh;
fi;
chmod 755 tools.csh;
./tools.csh
# now I have all the setenv commands effective ...
Ответ 9
Поиск csh файла в bash не будет работать. Вы можете изменить оболочку входа по умолчанию из csh в bash, если вы более удобны в bash. Вы можете использовать chsh или как администратор, чтобы изменить его для вас.
chsh -s /usr/local/bin/bash