无法访问2>& 1:如何将变量内容视为重定向而不是文件名

时间:2015-02-05 15:00:24

标签: linux bash io-redirection

如何根据变量内容控制流程输出重定向?我尝试了以下内容,但它将$redirect的内容视为文件名而不是重定向。

$ redirect="2>&1 >/dev/null"
$ ls -la $redirect
ls: cannot access 2>&1: No such file or directory
$ redirect=""
$ ls -la $redirect
total 376
drwx------ 1 wakatana users   4096 Feb  5 15:32 .
drwx------ 1 wakatana users   4096 Feb  2 18:44 ..
-rw------- 1 wakatana users    390 Feb  5 13:34 .bashrc

3 个答案:

答案 0 :(得分:4)

如果您接受更改命令的顺序,那么这是实现您想要的方法:使用别名。别名通常不受欢迎,并且,正如Bash手册中所述,对于几乎所有目的,别名都被shell函数所取代。

我们似乎已经在几乎违反行为了:

$ alias redirect='2>&1 > /dev/null'
$ redirect ls
$

没有eval

答案 1 :(得分:3)

发生ls错误是因为shell在执行参数扩展之前会扫描重定向(并且您可能会考虑重定向的顺序),并尝试列出名为2>&1和{{}的两个文件。 1}},就像你键入>/dev/null一样。做你想做的事情的方法是对所有重定向和替换进行第二次迭代。 ls '2>&1' '>/dev/null'内置版就是这样:

eval

如果您必须知道,the POSIX shell specification的订单是

  1. 根据Shell语法规则识别为变量赋值或重定向的单词将保存,以便在步骤3和4中进行处理。

  2. 非变量赋值或重定向的单词应为 扩大。如果任何字段在扩展后仍然存在,则第一个字段 字段应被视为命令名称,其余字段为 命令的参数。

  3. 重定向应按重定向中所述执行。

  4. 每个变量赋值都应扩展为波形扩展,参数扩展,命令替换,算术扩展和 在分配值之前引用删除。

  5. 这是一个不太复杂的重定向示例,用于说明正在发生的事情:

     eval ls -la $redirect
    

    正如Etan指出的那样,如果你不控制$ redirect=">file" $ echo foo $redirect foo >file $ eval echo foo $redirect $ cat file foo 的确切内容,eval可能不是一个合适的解决方案。想象一下redirect能做什么。

答案 2 :(得分:1)

2>&1的顺序需要撤消,更改:

$redirect="2>&1 >/dev/null"

$redirect=">/dev/null 2>&1"

编辑:

要在命令行上运行ls -al,更好的选择是:

$redirect="ls -al >/dev/null 2>&1"
eval $redirect

2>&1放在最后的目的是重定向命令生成的所有错误以及第一次重定向。