如何将 VAR 从子 shell 导出到父 shell?

如何将 VAR 从子 shell 导出到父 shell?

我有一个 Korn shell 脚本

#!/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 仅在子 shell 中导出,但我希望它们也在我的父 shell 中设置,因此当我在提示符下时这些 var 仍然设置正确。

我知道

. .myscript.sh

但是有没有不用“来源”的方法呢?因为我的用户经常忘记“来源”。


EDIT1:删除“exit 0”部分 - 这只是我未经思考就打字

EDIT2:添加更多关于为什么我需要这个的详细信息:我的开发人员为(为了简单起见)2 个应用程序编写代码:ABC 和 DEF。每个应用程序都由单独的用户 usrabc 和 usrdef 在生产中运行,因此已经设置了他们的 $BIN、$CFG、$ORA_HOME 等等 - 特定于他们的应用程序。

所以

  • 上述脚本中的 ABC 的 $BIN = /opt/abc/bin # $ABC_BIN
  • DEF 的 $BIN = /opt/def/bin # $DEF_BIN

ETC。

现在,在开发框上,开发人员可以在他们自己的用户帐户“justin_case”下同时开发 ABC 和 DEF,我让他们获取文件(上面),以便他们可以来回切换他们的 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

现在对我来说这更有意义了

答案1

我认为这是一个“无能为力”的问题……

首先 —— 您不会想因为末尾的 exit 0 而获取该脚本。

其次,没有一个 unix 子进程可以直接改变父进程的环境。否则,各种疯狂的事情都有可能发生。

您可以使用默认配置文件或 bashrc 文件向他们的环境中添加一些内容吗?或者您可以为他们尝试运行的任何程序编写一个包装器吗?

请允许我详细阐述一下“包装器”的概念。

假设您想要使用环境变量“OPTIONS”中的 PROD 或 DEV 来运行程序 snoopy,具体取决于您想要的是生产还是开发。如果未设置,假设 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 中实际的 snoopy 程序之前,并在脚本的 exec 语句中包含二进制文件的完整路径...

答案2

答案是采购。采购允许您在脚本中包含变量当前的shell,但绝不是它的父级。确实,您必须小心不要使用任何 exit 命令或类似命令,因为这会关闭您当前的 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 帐户)。请问你想实现什么?

相关内容