Bash 不使用';";“污染”;环境?
考虑以下两个脚本: envSetter.sh:Bash 不使用';";“污染”;环境?,bash,shell,Bash,Shell,考虑以下两个脚本: envSetter.sh: #!/bin/bash export ENV_VAR=6 return 3 sourceable.sh: #!/bin/bash function main() { local var=5 source envSetter.sh } main "$@" unset -f main envSetter.sh是一个脚本,用于设置一些变量(并可能执行影响当前shell(环境)的其他操作)。我需要创建一个可源
#!/bin/bash
export ENV_VAR=6
return 3
sourceable.sh:
#!/bin/bash
function main()
{
local var=5
source envSetter.sh
}
main "$@"
unset -f main
envSetter.sh
是一个脚本,用于设置一些变量(并可能执行影响当前shell(环境)的其他操作)。我需要创建一个可源代码的脚本,该脚本将源代码envSetter.sh
,但也会在自身完成后进行清理。即,在运行sourceable.sh
之后,我希望我的shell设置ENV_VAR
,但我不希望定义main
(或sourceable.sh
使用的任何其他内容)
上面的脚本实现了这一点。然而,最重要的是,我希望sourceable.sh
能够返回退出代码main
返回的任何内容。现在,脚本返回unset-f main
的结果。如果我删除该命令,我的脚本将保留我不希望定义的main
函数。如果我尝试使用临时变量:
main "$@"
result=$?
unset -f main
return $result
它将返回我期望的结果,但也将保留我不想要的已定义的result
。我也不能使用main
函数并将所有代码放在脚本的顶层,但这会暴露main
内部的更多垃圾(例如local var
),这也是我不想要的
有没有办法将
envSetter.sh
(即,让它在当前shell中设置变量),返回main
返回的内容,而不使用sourceable.sh
使用的内容“污染”我的当前shell?澄清一下:我希望envSetter.sh
影响我当前的shell,但我不希望sourceable.sh
影响。如何将unset
命令隐藏在main
函数中?像这样:
#!/bin/bash
main() {
unset -f main
local var=5
source envSetter.sh
}
main "$@"
请注意,返回状态只会在中传播,因为source envSetter.sh
是main
中的最后一个命令,它将成为main
的返回状态,同样,因为main
是脚本中的最后一个命令,它将成为脚本的返回状态
顺便说一句,在本应与源代码一起运行的东西上使用shebang没有多大意义。我倾向于使用这样的东西:
#!/bin/echo Run this script with the source or . command.
在返回陷阱中进行清理:
#!/bin/bash
trap 'unset -f main' RETURN
main()
{
local var=5
source envSetter.sh
}
main "$@"
您可以在子shell中获取脚本的源代码,并以可获取源代码的形式将所需的相关内容输出到stdout。像这样:
tmp=$(
var=5
# silence stdout so that it does not affect what we want
source envSetter.sh >&2
# modify the environment if you want to
unexport ENV_VAR
env_var="$ENV_VAR" # for example rename
# output the environment in a format you want
declare -p env_var ENV_VAR
# declare -f function1 function2 # for functions
# or printf "%q" "$ENV_VAR"
# or write it to a file printf "%s" "$ENV_VAR" > somefile
# ie. save the state where you want to
)
ret=$?
# Load hand picked variables.
eval "$tmp"
echo "ENV_VAR=$ENV_VAR ret=$ret"
只是一个地下地狱(source envSetter.sh}
?我也考虑过,但如果我使用subshellenvSetter.sh
将无法影响我当前的shell(例如setENV_VAR
)。你说的是不是“污染”我的当前shell
,然后决定。您想手工选择想要的变量吗?如果我的意图不够明确,很抱歉。但是我指定了:“不要用任何sourceable.sh
使用的东西“污染”我的当前shell”。源代码的退出代码只是源代码脚本中最后一个命令的退出代码。main
函数的用途是什么?如果您只是源代码脚本,那么退出代码将保存在$?
中。返回陷阱将保留在此之后,OP将不得不重置它。然后,返回陷阱-返回
在脚本中陷阱主体?@glennjackman这是我的一个想法,如果脚本是以交互方式来源的,它似乎是有效的。但是当从shell脚本来源时,它给出了一个语法错误。(unset-f main
INSIDEmain
完成了这个技巧,谢谢!我甚至认为这样的事情是不允许的。)