shell 字符串中的Bash进程替换

n6lpvg4x  于 2023-08-07  发布在  Shell
关注(0)|答案(2)|浏览(94)

我试图在脚本中添加一个开关,它将使内部命令中的参数成为可选参数。通常情况下,我会通过使用一个条件来运行命令(带参数或不带参数),或者如果参数很简单,只需在中创建一个带参数的字符串并替换它。如果不需要该参数,则字符串为空。
我有一个额外的复杂性,有一个空运行模式,只是打印命令,而不是运行它,所以已经有一个条件。因此,我只想创建一个字符串形式的内部参数,然后将其替换为空运行的echo或真实的命令。但是,该选项有点复杂,如下所示:

<(echo $msg_enc | base64 -d -)

字符串
这将获取一个以base64编码的字符串,对其进行解码,并将内容显示为一个可以读取的临时文件。我真的不能轻易地改变这个结构,所以我试着把它保存在一个字符串中,并计算它。为此,我创建了一个shell脚本call_just_print.sh和另一个小shell脚本来模拟命令just_print.sh

调用_just_print.sh打印文件

msg="hello world"
msg_enc="$(echo $msg | base64)"

dry_run=0
if [[ "${1}" == "dry-run" ]]; then
    dry_run=1
fi

enc_cmd=" <(echo \$msg_enc | base64 -d -)"
if [[ "${dry_run}" == "1" ]]; then
    echo "./just_print.sh ${enc_cmd}"
else
    ./just_print.sh "${enc_cmd}"
fi


这实际上只是从命令行中获取一个模拟运行提示,如果设置了,则只打印将要运行的命令,如果未设置,则将运行该命令。

只打印.sh

echo "[$(cat ${1})]"


它简单地接收一个假定为文件的参数,并将其显示到终端。理想情况下,在没有模拟运行模式的情况下运行时,输出将打印[hello world]。当我运行它时,我得到以下结果:

$ ./call_just_print.sh dry-run
./just_print.sh  <(echo $msg_enc | base64 -d -)
$ ./call_just_print.sh
cat: invalid option -- 'd'
Try 'cat --help' for more information.
[]


空运行模式工作正常,但在没有标志的情况下使用时,msg_enc var将逐字传递到just_print.sh,导致运行以下代码:cat '<(echo' '$msg_enc' '|' base64 -d '-)'这是绝对不对的。
我尝试在调用中使用eval,如下所示:

./just_print.sh "$(eval ${enc_cmd})"


但我发现,虽然这会导致变量的正确求值,从而创建临时文件,但它随后会尝试执行该文件:

./call_just_print.sh: line 15: /dev/fd/63: Permission denied


谁能告诉我哪里错了?

c3frrgcw

c3frrgcw1#

变更

./just_print.sh "${enc_cmd}"

字符串

eval "./just_print.sh ${enc_cmd}"


因此它将把变量展开的结果作为shell代码来计算。否则,它将被视为just_print.sh的文字参数。
使用eval时要非常小心--要执行的代码应该由脚本生成,而不是用户提供。

63lcw9qa

63lcw9qa2#

msg="hello world"
msg_enc="$(echo $msg | base64)"

dry_run="eval"
if [[ "${1}" == "dry-run" ]]; then
    dry_run="echo"
fi

enc_cmd=" <(echo \$msg_enc | base64 -d -)"
$dry_run "./just_print.sh ${enc_cmd}"

字符串
您使用eval的方法是正确的,但是您使它过于复杂了。您只需要重新构造它,使整个命令都是eval ed。
我还简化了您的逻辑,以便统一干运行命令和执行命令,从而避免丑陋且容易出错的if块。

相关问题