我有一行启动脚本:
pyprogramm >> /dev/null 2>&1 &
含义:
>> /dev/null - redirect stdout to null device
2>&1 - redirect stderr to stdout (that is redirected to null device)
但最后一个是什么&
意思呢?
答案1
& 终止符是什么?
命令末尾的尾随&
运算符用于将命令置于后台。这实际上是由POSIX 标准:
异步列表
如果命令以控制运算符 ('&') 结尾,则 shell 将在子 shell 中异步执行该命令。这意味着 shell 不应等待命令完成后再执行下一个命令。
后台运行命令的格式是:
命令1 & [命令2 & ... ]
后台命令的目的是运行命令,而不需要脚本中的主 shell 或交互式 shell 等待命令,这会阻止其他命令的执行,并给用户带来等待的不便。这对于启动长时间运行的命令但您需要在当前 shell 中继续工作。您可以猜到,这起源于没有多选项卡终端仿真器的时代,但终端是连接到计算机本身的实际物理硬件。
从定义中可以看出,它还&
充当命令列表的命令终止符,就像;
does 一样。在您的具体示例中,pyprogramm >> /dev/null 2>&1 &
列表中只有一个命令。
顺序 ; 列表 vs 异步 & 列表
更普遍,
echo Hello ; echo World ;
和
echo Hello & echo World &
;
这是两个由and运算符终止的列表示例&
。一个区别是,如果禁用作业控制,&
终止列表将具有连接到的输入:/dev/null
如果禁用作业控制(参见 set、-m),则在执行任何显式重定向之前,异步列表的标准输入应被视为分配给具有与 /dev/null 相同属性的文件。如果启用了作业控制,则不会发生这种情况。在所有情况下,标准输入的显式重定向应覆盖此活动。
stdin
但是,在顺序列表中,如果没有明确的重定向,则每个命令仍然连接到终端。
还要注意,根据我们前面提到的定义,&
在子 shell 中执行命令。相比之下,;
终止列表在当前 shell 中执行。退出状态也有所不同。&
标准规定:
异步列表的退出状态应为零。
当您想将多个命令放在后台时,这一点很重要。当您编写脚本或命令时,您必须选择那些您不关心它们是否失败的命令,或者您必须找到一种方法来处理非零(错误)退出状态。在您的特定示例中,pyprogramm >> /dev/null 2>&1 &
在后台运行应该有某种方式来指示它是否失败,但是判断您使用2>&1
重定向来隐藏错误输出,并且您可能假设脚本不会失败。
相比之下,;
退出状态定义为:
顺序列表的退出状态应为列表中最后一个命令的退出状态。
同样,这对您如何在命令行中编写连续的命令列表以及当列表中的某些命令失败时如何处理事情有影响。
附注和其他阅读材料
事实上,这是 POSIX 定义,意味着所有 Bourne 类 shell(即
bash
、dash
和 )都ksh
必须支持它。&
重定向不同于&
命令终止符。它意味着复制(拷贝)文件描述符对象。请参阅输出重定向中的 & 到底是什么意思?其中
bash
还有|&
运算符(注意管道符和 & 符号之间没有空格)。从bash 手册:如果使用 |&,则命令的标准错误除了其标准输出外,还将通过管道连接到命令 2 的标准输入;它是 2>&1 | 的简写。在命令指定的任何重定向之后,将执行将标准错误隐式重定向到标准输出的操作。
答案2
意思是在后台运行命令。调用脚本会继续执行,而不是阻塞,直到被调用的命令完成。
答案3
&
这会将脚本的控制权返回给操作系统,但会将响应发送到后台,而不是nohup
直接发送整个执行