0

我的脚本:

#!/bin/bash

generic()
{

    echo $1;
    $1 > temp.txt 2>&1
}

generic "echo asd > /dev/null 2>&1; echo temp"

预期结果:

  1. “asd”应该去 /dev/null
  2. “temp”应该进入 temp.txt 文件。

实际结果:

  1. “asd > /dev/null 2>&1; echo temp”进入 temp.txt 文件。

为什么只有第一个 echo 语句运行并且它的输出被重定向到 temp.txt。另外,为什么第二个命令被视为字符串?

4

1 回答 1

0

您需要阅读规范

(这是 POSIX sh 规范,因为 bash 没有真正的规范。bash 试图与 POSIX sh 兼容,但增加了不必要的复杂性。您应该#!/bin/sh作为初学者使用,并且每当您想编写一个健全的脚本时)

特别是,您不能在变量中存储除单个命令之外的任何内容。如果您像说 一样从变量执行$1,那么这将被解释为单个命令:

IFS在空格或变量内的任何内容上拆分发生。在您的示例中,这将导致以下令牌列表:

  1. 回声
  2. asd
  3. >
  4. /dev/null
  5. 2>&1;
  6. 回声
  7. 温度

然后这个列表作为一个进程执行,相当于用 C 编写execlp("echo", "echo", "asd", ">", "/dev/null", "2>&1;", "echo", "temp", NULL);

请注意,如果您"$1"改为编写,这将导致 shell 尝试启动一个echo asd > /dev/null 2>&1; echo temp不带参数调用的程序。

如果您想将字符串重新评估为 shell 命令行,则需要使用eval: eval "$1"。但请注意安全隐患!Eval 被许多人认为是邪恶的。

于 2013-09-29T11:08:34.017 回答