exec 3>&1 4>&2 1>>/tmp/output.log2>&1 在 bash 脚本中做什么?

  • 本文关键字:脚本 bash tmp exec log2 output bash
  • 更新时间 :
  • 英文 :


我在bash脚本中看到过这样的代码

exec 3>&1 4>&2 1>>/tmp/output.log 2>&1

据我所知,标准输出被重定向到新的fd 3,标准输出被重定向到4。那么1和2 fd保存了什么?重定向1>> file2>&1意味着什么?

我看到输出以及err从脚本写入/tmp/output.log

我希望脚本在运行时将标准输出和标准错误写入/tmp/output.log并在控制台中显示。重定向应该是什么样的?

exec 3>&1 4>&2 1>>/tmp/output.log 2>&1执行以下操作:

  1. 使文件描述符3为stdout的副本
  2. 使文件描述符4成为stderr的副本
  3. 重定向附加stdout到文件/tmp/output.log
  4. 使stderr成为stdout的副本

文件描述符3和4可能在这里用作临时存储,这样可以用exec 1>&3 2>&4恢复初始的stdoutstderr

第三次重定向将stdout以追加方式发送到/tmp/output.log。最后一次重定向使stderr成为stdout的副本,即也以追加方式将stderr发送给/tmp/output.log。注意,这4个重定向的顺序很重要。

我希望脚本将stdoutstderr写入/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

如果在你的脚本中的某一点,你想恢复stdoutstderr的原始状态,你可以使用相同的技巧,在你发现的例子:

$ 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
...

最新更新