无法访问 2>&1:如何将变量内容视为重定向而不是文件名
Cannot access 2>&1: How to treat variable content as a redirection not as filename
如何根据变量内容控制进程输出重定向?我试过以下,但它将 $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
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
放在最后的目的是重定向命令产生的所有错误以及第一次重定向。
ls
错误的发生是因为 shell 在执行参数扩展之前扫描重定向(您可能还会考虑重定向的顺序)并尝试列出两个名为 2>&1
和 >/dev/null
,就像您输入 ls '2>&1' '>/dev/null'
一样。做你想做的事情的方法是对所有重定向和替换进行第二次迭代。 eval
内置函数就是这样做的:
eval ls -la $redirect
非要知道,按照the POSIX shell specification的顺序是
根据Shell语法规则被识别为变量赋值或重定向的词被保存以供在步骤3和4中处理。
非变量赋值或重定向的词应为
展开。如果有任何字段在扩展后仍然存在,则第一个
字段应被视为命令名称,其余字段为
命令的参数。
重定向应按照重定向中的描述执行。
每个变量赋值都应该进行波浪符扩展、参数扩展、命令替换、算术扩展和
在分配值之前删除引号。
这里有一个不太复杂的重定向示例来说明正在发生的事情:
$ redirect=">file"
$ echo foo $redirect
foo >file
$ eval echo foo $redirect
$ cat file
foo
正如 Etan 指出的那样,如果您不控制 redirect
的确切内容,eval
可能不是合适的解决方案。想象一下 redirect='; rm -rf $HOME'
能做什么。
如果您接受更改命令的顺序,这是一种实现您想要的方法:使用别名。别名通常不受欢迎,而且,如 Bash 手册中所述,对于几乎所有用途,别名都被 shell 函数取代。
我们似乎处于 几乎 突破口:
$ alias redirect='2>&1 > /dev/null'
$ redirect ls
$
没有eval
.
如何根据变量内容控制进程输出重定向?我试过以下,但它将 $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
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
放在最后的目的是重定向命令产生的所有错误以及第一次重定向。
ls
错误的发生是因为 shell 在执行参数扩展之前扫描重定向(您可能还会考虑重定向的顺序)并尝试列出两个名为 2>&1
和 >/dev/null
,就像您输入 ls '2>&1' '>/dev/null'
一样。做你想做的事情的方法是对所有重定向和替换进行第二次迭代。 eval
内置函数就是这样做的:
eval ls -la $redirect
非要知道,按照the POSIX shell specification的顺序是
根据Shell语法规则被识别为变量赋值或重定向的词被保存以供在步骤3和4中处理。
非变量赋值或重定向的词应为 展开。如果有任何字段在扩展后仍然存在,则第一个 字段应被视为命令名称,其余字段为 命令的参数。
重定向应按照重定向中的描述执行。
每个变量赋值都应该进行波浪符扩展、参数扩展、命令替换、算术扩展和 在分配值之前删除引号。
这里有一个不太复杂的重定向示例来说明正在发生的事情:
$ redirect=">file"
$ echo foo $redirect
foo >file
$ eval echo foo $redirect
$ cat file
foo
正如 Etan 指出的那样,如果您不控制 redirect
的确切内容,eval
可能不是合适的解决方案。想象一下 redirect='; rm -rf $HOME'
能做什么。
如果您接受更改命令的顺序,这是一种实现您想要的方法:使用别名。别名通常不受欢迎,而且,如 Bash 手册中所述,对于几乎所有用途,别名都被 shell 函数取代。
我们似乎处于 几乎 突破口:
$ alias redirect='2>&1 > /dev/null'
$ redirect ls
$
没有eval
.