Как экспортировать VAR из подоболочки в родительскую оболочку?

10

У меня есть скрипт оболочки 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

теперь эти VAR экспортируются только в подоболочке, но я хочу, чтобы они также были установлены в моей родительской оболочке, поэтому, когда я получаю приглашение, эти переменные по-прежнему установлены правильно.

Я знаю о

. .myscript.sh

но есть ли способ сделать это без "источников"? так как мои пользователи часто забывают «источник».


РЕДАКТИРОВАТЬ1: убрав часть «выход 0» - я просто набрал текст, не думая сначала

РЕДАКТИРОВАТЬ 2: добавить больше подробностей о том, зачем мне это нужно: мои разработчики пишут код (для простоты) 2 приложений: ABC & DEF. каждое приложение запускается в производство отдельными пользователями usrabc и usrdef, следовательно, они настроили свои $ BIN, $ CFG, $ ORA_HOME, что угодно - в зависимости от их приложений.

так

  • $ BIN = / opt / abc / bin # $ ABC_BIN ABC в приведенном выше сценарии
  • DEF $ BIN = / opt / def / bin # $ DEF_BIN

и т.п.

Теперь разработчики могут разрабатывать ABC и DEF одновременно под своей собственной учетной записью пользователя 'justin_case', и я заставляю их использовать исходный файл (см. выше), чтобы они могли переключаться между своими настройками ENV var. ($ BIN должен указывать на $ ABC_BIN за один раз, а затем мне нужно переключиться на $ BIN = $ DEF_BIN)

теперь скрипт должен также создавать новые песочницы для параллельной разработки одного и того же приложения и т. д. Это заставляет меня делать это в интерактивном режиме, запрашивая имя песочницы и т. д.

  • / Главная / justin_case / sandbox_abc_beta2
  • / Главная / justin_case / sandbox_abc_r1
  • / Главная / justin_case / sandbox_def_r1

Другой вариант, который я рассмотрел, - это написание псевдонимов и добавление их в профиль каждого пользователя.

  • псевдоним 'setup_env =. .myscript.sh»

и запустить его с

  • setup_env параметр1 ... параметрX

это имеет больше смысла для меня сейчас

webwesen
источник
Да, вы можете сделать это с помощью псевдонима или функции (я сам предпочитаю функции), где у вас есть функция prod () {export VAR = snoopy; }; и функция dev () {export VAR = woodstock; };
Крис

Ответы:

11

Я думаю, что это проблема "не может сделать" ...

Во-первых, вы не захотите использовать этот скрипт из-за выхода 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" "$@"

Если вы не хотите гадить с реальным файлом, поместите этот скрипт куда-нибудь в файловую систему, которая будет впереди реальной программы snoopy в PATH пользователя, и укажите полный путь к двоичному файлу в инструкции exec скрипта ...

Крис
источник
5

Ответ на источник. Sourcing позволяет вам включать переменные в сценарий в текущую оболочку, но не является его родителем. Это правда, вы должны быть осторожны, чтобы не использовать какую-либо команду выхода или подобную, потому что это закроет вашу текущую оболочку.

Вы можете получить скрипт, используя ".", Т.е.

, ./myscript.ksh

txwikinger
источник
3

Может быть, если вы попробуете ...

#!/bin/bash

mknod fifo p

(
       echo 'value' > fifo &
)

VARIABLE=`cat fifo`
rm fifo

Это не совсем экспорт переменных, но он может обеспечить базовую связь с родительским процессом.

Оскар
источник
1

ОК, не смейся сейчас. Очень быстрое и очень грязное решение - добавить

echo "Please copy and paste this command:"
echo ""
echo "export BIN=\"$BIN\""

к вашему сценарию.

Другой подход . Просто execподчиненный $ SHELL в вашем скрипте, возможно, с другим приглашением (измените $ PS1, чтобы уведомить пользователей, в какой среде они работают, чтобы уменьшить путаницу).

Другой подход (мой любимый). Пользователи забывают написать ваш сценарий, почему это так? Sourcing - точно стандартный путь. Возможно, хороший способ напомнить им - удалить первую строку ( #!/bin/sh), а затем chmod a-xее. После этого он все еще может быть получен, но, очевидно, не может быть ошибочно выполнен.

Рэнт : В общем, я чувствую, что у тебя изначально была странная идея. Может быть, не странно ... Я бы сказал, что не в стиле Unix. Мне никогда не приходилось экспортировать окружение в родительскую среду в моей жизни. Однажды я видел похожую ситуацию - войти в систему .profile, спрашивая, какую из трех разных сред настроить для одной учетной записи оракула. Плохая идея, в конце концов оказалось, что пользователи предпочитают переходить на sudo (они используют sudo для трех разных учетных записей oraxxx). Чего вы пытаетесь достичь, если я могу спросить?

kubanczyk
источник