1

我已经从文件中读取了一行 bash 代码,我想将它发送到日志中。为了使它更有用,我想发送该行的可变扩展版本。

我只想扩展 shell 变量。我不想解释管道,也不想产生任何副进程,比如用$( rm -r /).

我知道变量扩展深深地融入了 bash。我希望有一种方法可以执行扩展,而不会产生任何副作用,这将来自管道、外部程序和——也许——here-documents。

也许有类似的东西eval

#!/bin/bash
linenr=42
line=`sed "${linenr}q;d" my-other-script.sh`
shell-expand $line >>mylog.log

我想要一种仅扩展 shell 变量的方法。如果x=aa="example"那么我想要以下扩展:

echo $x应该是echo a

echo ${a}应该echo example

touch ${!x}.txt应该touch example.txt

if [ (( ${#a} - 6 )) -gt 10 ]; then echo "Too long string"应该if [ 1 -gt 10 ]; then echo "Too long string"

echo "\$a and \$x">/dev/null应该echo "\$a and \$x>dev/null"

4

2 回答 2

2

对于那些五年后到达的人,虽然这不是 OP问题的最佳答案,但问题的答案如下。Bash 可以做间接参数扩展:

some_param=a
a=b
echo ${!some_param}
echo $BASH_VERSION
# 5.0.18(1)-release
于 2020-07-23T19:10:16.060 回答
0

你是绝对正确的,使用 bash 是非常危险的。实际上,您的命令受到您的问题的影响。

让我们详细讨论您的脚本:

#!/bin/bash
line=`sed "${42}q;d" my-other-script.sh`
shell-expand $line >>mylog.log

sed 可能会产生多行输出,因此使用名称会产生误导line

然后你没有引用 $line,这可能会产生模糊的效果:

$ x='| grep x'
$ ls -l $x
ls: cannot access |: No such file or directory
ls: cannot access grep: No such file or directory
-rw-rw-r-- 1 foo bar 34493 Nov 19 18:51 x
$

在这种情况下,管道不会被执行,而是传递给程序 ls。如果您有不受信任的输入,则很难编写健壮的 shell 脚本。

使用 eval 是邪恶的——我永远不会建议使用它,尤其是出于这样的目的!

另一种方法是在 perl 中,遍历 $ENV 数组并用 env 值替换所有 env 键。这样您就可以更好地控制可能发生的事情。

于 2014-11-25T16:59:22.187 回答