我正在尝试编写一个
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 安装程序的良好指南?
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 中没有设置任何选项,因为程序以某种方式直接从文件中获取它们。
source
d 的脚本。该脚本将依次调用您当前的脚本。
您当前的脚本需要与源脚本进行通信,告诉它要更改哪些内容。一种常见的方法是回显可以由调用者直接执行的变量赋值。例如:
printf 'export SCRIPT_HOME=%q\n' "$SCRIPTPATH"
将
printf
与
%q
一起使用可确保正确转义任何特殊字符。然后有
source
d 脚本
eval
内部脚本。eval "$(sudo install-script.sh)"
如果您想隐藏顶部脚本的
source
,您可以将其隐藏在别名或 shell 函数后面。
.bashrc
,您就可以巧妙地伪造直接脚本执行和动态环境配置。设置方法如下:
第 1 步:创建env_setup.sh
文件
.bashrc
中设置函数和别名之前,请确保
env_setup.sh
脚本存在于您计划管理它们的位置中,无论是在特定项目目录中还是在 PATH 中更具全局可访问性的位置。创建一个基本的 env_setup.sh
脚本,并导出必要的环境变量:
# Example env_setup.sh
export PATH="/usr/local/bin:$PATH"
export MY_ENV_VAR="some_value"
将此脚本保存在您经常工作的目录中,或将其放置在系统路径中的目录中,以确保它可供所有人访问。第 2 步:定义函数
首先,您需要在
.bashrc
文件中定义两个函数。这些函数对于管理脚本的来源至关重要,无论它们是在当前目录还是系统路径中的其他位置。
在文本编辑器中打开.bashrc
:
vim ~/.bashrc
添加以下功能:
# Function to source a script from the current directory
env_setup_func_dot() {
if [ -f "./env_setup.sh" ]; then
source ./env_setup.sh
else
echo "env_setup.sh not found in the current directory!"
return 1
fi
}
# Function to search and source the script from the PATH
env_setup_func_nodot() {
local script_path=$(which env_setup.sh)
if [ -n "$script_path" ]; then
source "$script_path"
else
echo "env_setup.sh not found in the PATH!"
return 1
fi
}
设置用户可以像实际脚本一样调用的别名可以增强可用性。以下是设置这些别名的方法:
alias ./env_setup.sh='env_setup_func_dot'
alias env_setup.sh='env_setup_func_nodot'
.bashrc
.bashrc
:
source ~/.bashrc
通过此设置,您可以有效地模仿直接执行脚本并以最初看似禁止的方式管理 shell 环境。
注意事项