什么是“exec 1> / var / opt / log / my_logs / MYPROG_`date’+%Y%m%d_%H%M%S’`.log 2>&1”做什么?

我试图了解下面的shell脚本正在做什么。 我知道没有任何参数的exec重定向当前shell的输出但是我无法理解下面的命令的作用:

exec 1>/var/opt/log/my_logs/MYPROG_`date '+%Y%m%d_%H%M%S'`.log 2>&1 

实际上有4个重要信息正在发生:

  1. 内置的exec用于将命令行会话的所有输出重定向到文件

  2. 1>告诉shell重定向stdout标准流 ,即命令的正常非错误输出将转到 。 如果不存在,则>将创建;如果已存在,则将截断。

  3. 重定向的文件名是通过添加的反引号创建的, date '+%Y%m%d_%H%M%S'命令。 反引号是命令替换的forms,在function上等同于$(date '+%Y%m%d_%H%M%S')forms,现在$(...)是可读性的首选,因为这种forms可以是容易嵌套(即有多个级别)。 因此,使用指定格式'+%Y%m%d_%H%M%S'输出date将创建带时间戳的文件名。 如果您的命令在2018年7月4日4:20:20运行,则输出将为/var/opt/log/my_logs/MYPROG_20180704_042020.log

  4. 2>&1还将stderr流重定向到该文件,它是一个标准的,符合POSIX(这意味着除了bash之外的类似Bourne的shell)了。 这在function上等同于&> bash特定的语法。 shell中指定重定向的顺序很重要,因此在1>重定向后出现这种情况的原因。

总之,该命令本身不应该有输出。 它应该只重新连接所有连续命令的两个输出流,以进入您指定的文件。

有趣的是,使用这个命令,我的bash 4.4所有内容输出到文件,包括提示和我输入的任何内容(所以在这里我必须盲目地键入echo hello world并按Ctrl + D然后退出):

 $ bash --posix bash-4.4$ exec 1>./mylog_`date '+%Y%m%d_%H%M%S'`.log 2>&1 $ cat ./mylog_20180424_010800.log bash-4.4$ echo hello world hello world bash-4.4$ exit 

一点一点地做,显示bash输出提示stderr流,令人惊讶的是我输入的任何内容:

 bash-4.4$ exec 1> ./mylog.txt bash-4.4$ echo Hello World bash-4.4$ cat ./mylog.txt cat: ./mylog.txt: input file is output file bash-4.4$ exec 2>&1 

ksh情况下,同样的事情发生,但我可以看到正在输入的内容,只有提示转到文件,即stdin没有被重定向:

 bash-4.4$ ksh $ exec 1>./mylog 2>&1 echo hello askubuntu bash-4.4$ cat ./mylog $ hello askubuntu $ bash-4.4$ 

所以在这里我们可以看到shell可以选择将提示PS1输出到其中一个标准流,以便将其包含到文件中。