我在bash脚本中看到过这样的代码
exec 3>&1 4>&2 1>>/tmp/output.log 2>&1
据我所知,标准输出被重定向到新的fd 3,标准输出被重定向到4。那么1和2 fd保存了什么?重定向1>> file
和2>&1
意味着什么?
我看到输出以及err从脚本写入/tmp/output.log
。
我希望脚本在运行时将标准输出和标准错误写入/tmp/output.log
并在控制台中显示。重定向应该是什么样的?
exec 3>&1 4>&2 1>>/tmp/output.log 2>&1
执行以下操作:
- 使文件描述符3为
stdout
的副本 - 使文件描述符4成为
stderr
的副本 - 重定向附加
stdout
到文件/tmp/output.log
- 使
stderr
成为stdout
的副本
文件描述符3和4可能在这里用作临时存储,这样可以用exec 1>&3 2>&4
恢复初始的stdout
和stderr
。
第三次重定向将stdout
以追加方式发送到/tmp/output.log
。最后一次重定向使stderr
成为stdout
的副本,即也以追加方式将stderr
发送给/tmp/output.log
。注意,这4个重定向的顺序很重要。
我希望脚本将stdout
和stderr
写入/tmp/output.log
以及在控制台中显示,而它正在运行。重定向应该是什么样的?
使用进程替换将stdout
重定向到tee -a /tmp/output.log
命令。然后将stderr
重定向到stdout
。例子:
$ cat foo
#!/usr/bin/env bash
# redirect
exec 1> >( tee -a /tmp/output.log ) 2>&1
ls -z
echo "foo"
$ ./foo
ls: invalid option -- 'z'
Try 'ls --help' for more information.
foo
$ cat /tmp/output.log
ls: invalid option -- 'z'
Try 'ls --help' for more information.
foo
如果在你的脚本中的某一点,你想恢复stdout
和stderr
的原始状态,你可以使用相同的技巧,在你发现的例子:
$ cat foo
#!/usr/bin/env bash
# redirect
exec 3>&1 4>&2 1> >( tee -a /tmp/output.log ) 2>&1
ls -z
echo "foo"
...
# restore
exec 1>&3 2>&4
...