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

问题描述 投票:0回答:3

我正在尝试编写一个

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 安装程序的良好指南?

linux bash shell
3个回答
4
投票
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 中没有设置任何选项,因为程序以某种方式直接从文件中获取它们。


3
投票
source

d 的脚本。该脚本将依次调用您当前的脚本。


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

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

printf

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

然后有

source

d 脚本

eval
内部脚本。

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

如果您想隐藏顶部脚本的 
source

,您可以将其隐藏在别名或 shell 函数后面。

    


0
投票
.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 }

第 3 步:创建别名

设置用户可以像实际脚本一样调用的别名可以增强可用性。以下是设置这些别名的方法:

alias ./env_setup.sh='env_setup_func_dot' alias env_setup.sh='env_setup_func_nodot'

第 4 步:重新加载 

.bashrc


要应用这些更改并使函数和别名在当前会话中可用,请重新加载您的 

.bashrc

:

source ~/.bashrc

通过此设置,您可以有效地模仿直接执行脚本并以最初看似禁止的方式管理 shell 环境。

注意事项

在别名中使用点是非常规的,可能会导致混乱,因为很容易将此类别名误认为是通常为可执行文件或脚本保留的文件名或命令。虽然此设置在技术上可行,但如果在协作环境中共享或在生产环境中部署,则必须确保清楚地记录此类使用情况。

© www.soinside.com 2019 - 2024. All rights reserved.