如何在执行命令行之前回显命令行?

时间:2017-04-13 13:19:07

标签: bash ksh

我需要执行命令,我需要显示我执行的命令。所以我一直在尝试将命令存储在变量中并执行该变量。在显示输出时,我打印变量值如下所示。

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

3 个答案:

答案 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上有所改进(适用于evalbash):

注意:由于此命令由 构建,因此您可以完全控制命令字符串,因此可以接受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 的原始命令行。

    • 请注意ceving's answer中的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