
У меня есть скрипт оболочки Korn
#!/bin/ksh
# set the right ENV
case $INPUT in
abc)
export BIN=${ABC_BIN}
;;
def)
export BIN=${DEF_BIN}
;;
*)
export BIN=${BASE_BIN}
;;
esac
# exit 0 <- bad idea for sourcing the file
Теперь эти переменные экспортируются только в дочерней оболочке, но я хочу, чтобы они были установлены и в моей родительской оболочке, чтобы при появлении приглашения эти переменные по-прежнему были установлены правильно.
Я знаю о
. .myscript.sh
но есть ли способ сделать это без «источника»? так как мои пользователи часто забывают указывать «источник».
EDIT1: удалил часть «exit 0» — это просто я набрал не подумав
EDIT2: чтобы добавить больше подробностей о том, зачем мне это нужно: мои разработчики пишут код для (для простоты) 2 приложений: ABC и DEF. Каждое приложение запускается в рабочей среде отдельными пользователями usrabc и usrdef, поэтому они настраивают свои $BIN, $CFG, $ORA_HOME и т. д. - специфичные для их приложений.
так
- ABC's $BIN = /opt/abc/bin # $ABC_BIN в приведенном выше скрипте
- $BIN DEF = /opt/def/bin # $DEF_BIN
и т. д.
Теперь на dev-боксе разработчики могут разрабатывать ABC и DEF одновременно под своей учетной записью пользователя «justin_case», и я заставляю их указывать исходный файл (выше), чтобы они могли переключать свои настройки переменных среды туда и обратно. ($BIN должен указывать на $ABC_BIN в один момент времени, а затем мне нужно переключиться на $BIN=$DEF_BIN)
теперь скрипт должен также создавать новые песочницы для параллельной разработки того же приложения и т. д. это заставляет меня делать это интерактивно, запрашивая имя песочницы и т. д.
- /home/justin_case/sandbox_abc_beta2
- /home/justin_case/sandbox_abc_r1
- /home/justin_case/sandbox_def_r1
Другой вариант, который я рассматривал, — это написание псевдонимов и добавление их в профиль каждого пользователя.
- псевдоним 'setup_env=. .myscript.sh'
и запустите его с помощью
- параметр_env setup1 ... параметрX
Теперь это имеет для меня больше смысла
решение1
Я думаю, что это проблема из разряда «невозможно сделать»...
Во-первых, вам не захочется ссылаться на этот скрипт из-за выхода 0 в конце.
Во-вторых, ни один дочерний процесс unix не может напрямую изменять среду родителя. В противном случае были бы возможны всякие безумные вещи.
Не могли бы вы что-нибудь добавить в их среду с помощью профиля по умолчанию или файлов bashrc, или могли бы вы написать оболочку для той программы, которую они пытаются запустить?
Позвольте мне подробнее остановиться на концепции «обертки».
Допустим, вы хотите запустить программу snoopy с PROD или DEV в переменной окружения "OPTIONS" в зависимости от того, хотите ли вы производство или разработку. ЕСЛИ она не установлена, допустим, snoopy делает что-то нелепое, например, стирает базу данных для производства и разработки...
переименуйте «snoopy» в snoopy.bin (или .snoopy.bin)
затем поместите в то же место скрипт под названием «snoopy», содержащий следующее:
#!/bin/sh
export OPTIONS
case "$OPTIONS"
in
PROD) ;;
DEV) ;;
*) OPTIONS=DEV ;;
esac
#the binary is actually named snoopy.bin
exec "$0.bin" "$@"
Если вы не хотите возиться с самим файлом, поместите этот скрипт куда-нибудь в файловой системе, чтобы он находился выше реальной программы-шпиона в переменной PATH пользователя, и укажите полный путь к двоичному файлу в операторе exec скрипта...
решение2
Ответ — источник. Источник позволяет включать переменные в скрипт втекущийshell, но никогда не родитель этого. Это правда, вам нужно быть осторожным, чтобы не использовать команду выхода или что-то подобное, потому что это закроет вашу текущую оболочку.
Вы можете получить скрипт, используя «.», т.е.
. ./myscript.ksh
решение3
Может быть, если вы попробуете...
#!/bin/bash
mknod fifo p
(
echo 'value' > fifo &
)
VARIABLE=`cat fifo`
rm fifo
Это не совсем экспорт переменных, но он может обеспечить базовую связь с родительским процессом.
решение4
Ладно, не смейтесь сейчас. Очень быстрое и очень грязное решение — добавить
echo "Please copy and paste this command:"
echo ""
echo "export BIN=\"$BIN\""
к вашему сценарию.
Другой подход. Просто exec
подчиненный $SHELL в вашем скрипте, возможно, с другим приглашением (измените $PS1, чтобы уведомить пользователей, в какой среде они работают, чтобы избежать путаницы).
Другой подход(мой любимый). Пользователи забывают указать источник вашего скрипта, почему? Источник — это как раз стандартный способ. Возможно, хорошим способом напомнить им об этом будет удалить первую строку ( #!/bin/sh
), а затем chmod a-x
ее. После этого его все еще можно указать источник, но он, очевидно, не может быть ошибочно выполнен.
Рэнт: В общем, мне кажется, что у вас изначально была странная идея. Может, и не странная... Я бы сказал, несколько не в стиле Unix. Мне никогда в жизни не приходилось экспортировать окружение в родительский. Однажды я видел похожую ситуацию — login .profile спрашивал, какое из трех разных окружений установить для одной учетной записи oracle. Плохая идея, в итоге оказалось, что пользователи предпочли перейти на sudo (они использовали sudo для трех разных учетных записей oraxxx). Чего вы пытаетесь добиться, если можно так спросить?