提问人:Adriano_Pinaffo 提问时间:8/6/2023 最后编辑:Adriano_Pinaffo 更新时间:8/8/2023 访问量:109
如何在 bash 中通过 ref 将参数传递给脚本
How to pass an argument to a script by ref in bash
问:
请注意,我说的是将参数 by-ref 传递给脚本,而不是函数。我已经检查了这里和这里,他们讨论了使用函数传递参数。
我想要的是调用一个脚本,将一个参数传递给它,并使参数成为 shell 中的变量,并在脚本中分配值(这正是命令发生的情况,其中 RESPONSE 成为当前 shell 中的变量,其值由命令分配)。read RESPONSE
read
我知道使用这样的函数(使用):local -n
#!/bin/bash
function boo() {
local -n ref=$1
ref="new"
}
SOME_VAR="old"
echo $SOME_VAR
boo SOME_VAR
echo $SOME_VAR
或者像这样(使用):eval
function booeval() {
ref=$1
eval $(echo $ref=\"new\")
}
SOME_VAR="old"
echo $SOME_VAR
booeval SOME_VAR
echo $SOME_VAR
按预期工作。但是(或/)不能在函数之外工作,并且似乎在子shell中运行,当脚本结束时,变量不会在shell中生存。我想要这样的东西:local
declare
typedef
eval
$ cat /tmp/test.sh
#!/bin/bash
ref=$1
eval $(echo "export $ref=\"new value\"")
$ /tmp/test.sh VAR
$ echo $VAR
$
有什么想法吗?
答:
正如您无疑知道的那样,在子 shell 中分配的内容将保留在子 shell 中。
正如注释中所指出的,一种解决方案是没有子 shell:如果脚本是 d,则将保留赋值。但是,这需要仔细编写脚本,以免产生不必要的副作用。source
如果正常调用脚本(作为子 shell),您可能能够解决复杂 IPC 传递值的问题,但在我看来,您可以通过简单地让脚本输出值而不是尝试将其分配给任何内容来完全绕过复杂性:
var=$(script)
您可以使用第一种方法将其包装起来,以便可以传入变量名称:
assign_to(){
local -n ref=$1
shift
ref=$("$@")
}
例如:
$ myref=myvar
$ assign_to $myref date +%Y
$ declare -p myvar
declare -- myvar="2023"
$
评论
read
myref=myvar; mapfile -d '' $myref < <(date +%Y); declare -p myvar
不支持“按引用”。bash
有很多方法可以解决它,使用 f.e. STDIO 或使用单独的文件。
如果使用单个变量,则 STDIO 的工作原理很简单:
parent_shell_var=$(bash script)
并且只是您要导出的值。echo
文件可以按以下方式使用: 父脚本:
#!/bin/bash
hop=0
echo $hop
bash child_script tempfile
. tempfile
rm tempfile
echo $hop
child_script:
#!/bin/bash
echo "hop=1" > "$1"
这些是非常简单的示例,可以替代参数的 by-ref 传递。这些适用于单独的脚本和下标。
感谢大家为回答这个问题所做的努力。我最终将选择使用作为参数传递的参数来设置环境变量。只要我做sudo,它就会很好用。gdb
这并不是一个没有非常谨慎的解决方案,因为你会调用内部 bash 函数,事情可能会搞砸。但总的来说,它会运行得很好。
检查一些取消设置只读变量的方法,我偶然发现使用 gdb 直接调用该函数。因此,我应用了相同的逻辑,并从脚本中设置了一个新变量。它“有点”有效,但并不顺利:unbind_variable()
$ cat /tmp/test.sh
#!/bin/bash
ref="$1"
value="Value assigned from inside the script"
bashpid=$(ps -oppid,pid,cmd | grep $0 | grep -v grep | cut -f1 -d' ')
sudo gdb -ex 'call (int) setenv("'"$ref"'","'"$value"'",1)' --pid=$bashpid --batch 2>/dev/null 1>&2
当我称它为:
$ declare -p VARPASSED
bash: declare: VARPASSED: not found
$ /tmp/test.sh VARPASSED
$ declare -p VARPASSED
declare -x VARPASSED="Value assigned from inside the script"
现在,传递的变量已正确分配给当前 shell。问题是 gdb 需要附加到当前的 shell,这有点烦人。他们是如何处理命令的?sudo
read
PS:请在获取 bash pid 的路上减少一些松弛,我知道有更有效的方法可以做到这一点。那不是我的重点;)
评论
eval
ssh-agent
eval
无法在父级中设置变量,这就是问题所在
eval "$(ssh-agent -s)"
ssh-agent -s
评论
source