获取bash脚本以更新父shell的环境

时间:2016-08-02 21:20:00

标签: linux bash shell

我正在尝试编写一个bash命令行工具,该工具在安装后立即可用,即在调用其安装脚本的同一个shell中。让我们说install-script.sh(专为Ubuntu设计)看起来像:

# Get the script's absolute path:
pushd `dirname $0` > /dev/null
SCRIPTPATH=`pwd`
popd > /dev/null

# Add lines to bash.bashrc to export the environment variable:
echo "SCRIPT_HOME=${SCRIPTPATH}" >> /etc/bash.bashrc
echo "export SCRIPT_HOME" >> /etc/bash.bashrc

# Create a new command:
cp ${SCRIPTPATH}/newcomm /usr/bin
chmod a+x /usr/bin/newcomm

我们的想法是新命令newcomm使用SCRIPT_HOME环境变量来引用主脚本 - 这也在SCRIPTPATH中:

exec "${SCRIPT_HOME}/main-script.sh"

现在,更新后的bash.bashrc尚未加载到父shell中。更糟糕的是,我不能在脚本中source它 - 它在子shell中运行。使用export更改父shell中的SCRIPT_HOME充其量只会导致问题,但即使这样也是不可能的。另请注意,安装脚本需要使用sudo运行,因此无法使用source从父shell调用它。

应该可以,因为像apt这样的包管理器可以做到这一点。是否有强大的方法来修补我的方法?这通常是怎么做的,是否有编写bash安装程序的良好指南?

2 个答案:

答案 0 :(得分:3)

修改当前shell的唯一方法是获取脚本。这是不可避免的,所以从那里开始吧。写一个source d的脚本。该脚本将依次调用您当前的脚本。

您当前的脚本需要与源代码进行通信才能告诉它要更改的内容。常见的方法是回显可由调用者直接执行的变量赋值。例如:

printf 'export SCRIPT_HOME=%q\n' "$SCRIPTPATH"

printf%q一起使用可确保正确转义任何特殊字符。

然后让source d脚本eval成为内部脚本。

eval "$(sudo install-script.sh)"

如果要隐藏顶级脚本的source,可以将其隐藏在别名或shell函数后面。

答案 1 :(得分:3)

你做不到。也不能apt

包管理器只需将所需的数据/变量写入文件,这些文件可由程序本身,程序补丁或包装程序读取。

/etc/default/*中可以找到很好的例子。这些是具有可变定义的文件,有些甚至有助于描述它们的来源:

$ cat /etc/default/ssh
# Default settings for openssh-server. This file is sourced by /bin/sh from
# /etc/init.d/ssh.

# Options to pass to sshd
SSHD_OPTS=

您会注意到在安装软件包后,当前shell中没有设置任何选项,因为程序会以某种方式直接从文件中获取它们。