我需要执行命令,我需要显示我执行的命令。所以我一直在尝试将命令存储在变量中并执行该变量。在显示输出时,我打印变量值如下所示。
var="ls -ltr";
echo "$var \n `$var`";
上面一个是按照我的意愿提供输出,但是当我使用下面提到的命令时,它会给我一个错误。有人建议我如何存储下面提到的命令。
var="ls -ltr|wc -l";
echo "$var \n `$var`";
输出错误:
ls -ltr | wc -l
ls: cannot access |: No such file or directory
ls: cannot access wc: No such file or directory
将命令存储在变量中的正确方法是什么,如下面的命令。或者给我任何替代建议来满足我的要求。
cat passwd.txt|tr ' ' '\n'|egrep -i "$pwd_in"|sort
答案 0 :(得分:3)
将您的命令放入函数中并启用xtrace
。
cmd ()
{
set -x
ls -ltr | wc -l
set +x
}
答案 1 :(得分:2)
您的方法不起作用的原因是 shell元字符(例如|
)在嵌入 字符串时会失去其语法含义即可。 this related question的答案解释了原因;这个问题是关于嵌入式引用,但答案仍然类似
此外,它是generally ill-advised to store commands in variables;简而言之:
eval
,它只适用于简单命令(在控制操作符如{的帮助下,不是由多个命令组成的命令{1}}和|
),要得到您想要的内容,就无法使用&&
,即generally discouraged for security reasons。
eval
的字符串,则仅使用eval
;也就是说,使用eval
,例如,变量eval
($var
)可接受,当且仅当 > 强>:
eval "$var"
的值,知道它是一个命令,并知道它按预期工作(如果是 part 值由外部来源提供,下一点适用)$var
值的任何外部贡献的来源(是否完全形成$var
的值或部分) - 具体而言,您需要确保不会尝试恶意提供/注入不需要的命令。 最可预测的基于$var
的解决方案如下所示,在AxT_8041's answer上有所改进(适用于eval
和bash
):
注意:由于此命令由 构建,因此您可以完全控制命令字符串,因此可以接受ksh
< em>在这种情况下。
eval
使用更复杂的命令行来引用命令变得棘手,在这种情况下,您可以使用 here-document :
cmdLine='ls -ltr|wc -l'
printf "%s\n" "$cmdLine"; eval "$cmdLine"
注意:虽然这个命令也是由你构建的,但它是通过合并变量# Read the command into variable $cmdLine.
read -d '' -r cmdLine <<'EOF'
cat passwd.txt|tr ' ' '\n'|egrep -i "$pwd_in"|sort
EOF
printf "%s\n" "$cmdLine"; eval "$cmdLine"
的值来形成的,所以为了在这里安全地使用$pwd_in
,你必须知道或信任 eval
具有预期的价值,特别是它不包含尝试注入命令。
安全但有限的解决方案是使用shell提供的诊断功能:
在$pwd_in
的情况下,bash
会在执行前自动回显每个原始命令行(无需先在变量中定义感兴趣的命令):
set -v
这会产生,例如:
set -v # Turn echoing of raw command lines on.
ls -ltr | wc -l # Execute the command of interest.
set +v # Turn back off.
但是,有一些限制:
将Bash回声发送到 stderr 的原始命令行。
ls -ltr | wc -l
15
set +v
是相关功能,但其工作方式不同:它将单独回显简单命令({{ 1}}和set -x
)以已展开的形式构成管道。根据我的判断,无法抑制ls -ltr
输出行。
您可以尝试解决这些问题,但这并不容易或漂亮。
答案 2 :(得分:0)
以下是Bash的工作。试试这个:
var="ls -ltr|wc -l";
echo -e "$var \n `eval $var`";
Output:
ls -ltr|wc -l
10