为什么用'&'运行Linux shell命令?


30

我正在使用Red Hat Linux Enterprise版本5。我注意到人们有时会运行带有两个&选项的命令。例如,在以下命令中,有两个&符号。他们的目的是什么?它们是否总是与nohup一起使用?

nohup foo.sh <script parameters> >& <log_file_name> &

Answers:


15

除了马丁,阿什和凯文的答案外,有时您还会看到在数学上用于与位*的“&”号

$ echo $(( 11 & 7 ))
3

如果您不熟悉位运算符:

11: 1011
 7: 0111
-------- AND
 3: 0011

在每个位置的第一个数字和第二个数字中都有一个位,将答案中的该位设置为一个。

* Kevin答案中的功能称为逻辑 AND。

为了详细说明Ash的答案,在用于重定向符时,“&”号可以告诉Shell复制文件描述符。在此命令中echo "hello" > outputfile 2>&1,“&”号会使可能出现标准错误(stderr,文件描述符2)的所有输出与标准输出(stdout,文件描述符1,左侧的默认值)一起到达同一位置>。该>& outputfile运营商的简写> outputfile 2>&1

另外,Bash 4中的新增功能在case命令中有两个子句终止符;&;;&它们会影响案例是否“掉线”,如果发生,则是否执行下一个测试。


太好了,丹尼斯!假设我使用ssh终端登录计算机,然后使用ssh的终端执行命令(假设是一个长期运行的进程),然后如果我退出终端会话,那么该命令的长期运行将被正确终止吗?而且,即使退出外壳程序,我也希望命令继续执行,我应该使用nohup或&(在命令末尾)还是同时使用nohup和&?
2010年

1
@ George2:否,>& filename将stdout和stderr都输出到同一文件。如果您只想重定向stderr(并保留stdout),则可以这样做2> filename。至于其他问题,您很可能会同时使用nohup&
暂停,直到另行通知。

1
@ George2:如果不后台执行命令,则不会返回shell提示,因此可以发出logoutor exit命令。
暂停,直到另行通知。

2
乔治:如果您不使用&,那么您将永远不会提示您执行其他任何操作。终端将一直处于“挂起”状态,直到该过程(无论该过程如何)结束或被终止/终止。&保证进程在后台运行。但是,如果注销,则操作系统将终止所有进程,这也会杀死后台进程。如果使用nohup, 则会告诉进程“忽略将终止您的命令”。
Martin Marconcini 2010年

1
@ George2:是的。“免于挂断” ==“进程继续”和“ non-tty” ==“退出终端控制台会话”
暂停,直到另行通知。

32

在Bash shell脚本中,“&”号用于派生进程:

find -name hello &

这将导致find命令被派生并在后台运行(您始终可以通过其PID杀死它)。


谢谢马丁,假设我使用ssh终端登录计算机,然后使用ssh的终端执行命令(假设是一个长期运行的进程),然后如果我退出终端会话,则该命令的长期运行将正确终止?如果我在ssh终端中使用&执行命令,即使我退出终端,命令的长期运行过程仍在运行,对吗?
George2

1
那是正确的乔治。后台进程应继续进行,直到退出或您杀死它们为止。但是,正如已经指出的那样,您将不需要nohup来避免该过程在用户注销时终止。
Martin Marconcini 2010年

谢谢马丁!我想知道为什么我们需要同时使用&和nohup,以及它们各自的功能是什么,这些功能使我们实现了即使终端控制台退出也可以继续运行命令的目标。我阅读了nohup的手册页,并提到“运行不受挂断的命令,输出到非tty的命令”,我困惑于不受挂断的影响是您的意思是让命令继续运行而不受退出的影响终端控制台?如果是这样,我认为使用nohup就足够了,并且不需要使用&。任何意见?
2010年

1
您需要使用Both,如果不使用&,则终端将不允许您输入任何其他命令。您看到它的最佳方式就是尝试一下。一个很好的例子是一个命令,它需要一些时间,例如查找:find -name SomeName /> somefile.txt,尝试使用nohup和&进行查找,并查看它们之间的区别。
Martin Marconcini 2010年

这对于nohup问题有很好的答案:serverfault.com/questions/311593/…–
joshperry

26

为什么用'&'运行Linux shell命令?

若要立即返回提示,请在后台运行该过程。

它们的功能是什么?

nohup允许后台进程即使在用户注销(或退出启动外壳程序)后仍继续运行。

>& 将标准输出和标准错误都重定向到日志文件中。

在后台运行整个过程,立即提示您。

说明:

每个Linux进程都会打开三个I / O通道,一个输入“ stdin”,一个标准输出“ stdout”和一个标准错误输出“ stderr”。它们可以用于二进制,但传统上是文本。当大多数程序看到stdin关闭时,它们退出(程序员可以更改)。

当父shell退出时,stdin在子级上关闭,并且(通常,通常)子级也退出。此外,孩子们还会收到软件信号SIGHUP,它指示用户已“挂断”(以前是调制解调器),并且默认情况下也将退出。(请注意,程序员在编写程序时可以更改所有这些功能)。

因此,nohup的作用是为子进程提供一个单独的I / O环境,将输入和输出绑定到未绑定到父shell的东西上,并使子进程免受SIGHUP信号的影响。一旦用户断开连接,您将看到init拥有的nohup后台进程(进程1),而不是用户的外壳程序。

但是,nohup如果该进程在前台运行,则无法完全完成该工作,因此&被用于在后台运行程序,无论用户是否登录,该程序都可以在其中保持运行状态。


假设我使用ssh终端登录计算机,然后使用ssh的终端执行命令(假设是一个长期运行的进程),然后如果我退出终端会话,那么该命令的长期运行将被正确终止吗?而且,即使退出外壳程序,我也希望命令继续执行,我应该使用nohup或&(在命令末尾)还是同时使用nohup和&?
George2 2010年

1
正确,在SSH断开连接后,请同时使用nohup和&,以使该过程继续。
kmarsh 2010年

感谢Kmarsh!我想知道为什么我们需要同时使用&和nohup,以及它们各自的功能是什么,这些功能使我们实现了即使终端控制台退出也可以继续运行命令的目标。我阅读了nohup的手册页,并提到“运行不受挂断的命令,输出到非tty的命令”,我困惑于不受挂断的影响是您的意思是让命令继续运行而不受退出的影响终端控制台?如果是这样,我认为使用nohup就足够了,并且不需要使用&。任何意见?
George2

1
我将编辑答案以作答。
kmarsh 2010年

13

除了@Martin的答案之外:&符的其他用法(>&如上所述)是同时捕获 stdoutstderr。通常,如果将输出重定向到仅包含'>'的文件,则只会将输出重定向到,而不会stdout丢失任何错误。


1.感谢Ash,我想向您确认“>&<日志文件名>”,将所有stderr和stdout转储到日志文件中,对吗?2.并使用“> <日志文件名>”将所有标准输出转储到日志文件,对吗?
2010年

1
@乔治:是的,是的。
Ash Ash,2010年

谢谢阿什!我想知道为什么我们需要同时使用&和nohup,以及它们各自的功能是什么,这些功能使我们实现了即使终端控制台退出也可以继续运行命令的目标。我阅读了nohup的手册页,并提到“运行不受挂断的命令,输出到非tty的命令”,我困惑于不受挂断的影响是您的意思是让命令继续运行而不受退出的影响终端控制台?如果是这样,我认为使用nohup就足够了,并且不需要使用&。任何意见?
George2

4

除了Martin和Ash的答案以外,有时您可能还会看到&&令牌的使用。用来表示“仅当第一个命令成功运行时才运行第二个命令”。编写正确的命令(如果有任何错误)将不会成功退出。

[kevin@box ~]$ ls file && echo removing file && rm file
ls: file: No such file or directory
[kevin@box ~]$ touch file
[kevin@box ~]$ ls file && echo removing file && rm file
file
removing file
[kevin@box ~]$

酷,凯文!假设我使用ssh终端登录计算机,然后使用ssh的终端执行命令(假设是一个长期运行的进程),然后如果我退出终端会话,那么该命令的长期运行将被正确终止吗?而且,即使退出外壳程序,我也希望命令继续执行,我应该使用nohup或&(在命令末尾)还是同时使用nohup和&?
George2

任一个都会起作用。我想(但完全是猜测),NOHUP是执行此操作的原始方法,但是背景现在可以使用了。一个重要的区别是,通过挂入远程系统来运行交互式Shell时。NOHUP进程将在前台运行,但是如果退出则将继续运行,而后台进程将在生成命令后立即返回。但是,当您尝试使用在后台运行的命令退出交互式外壳程序时,会首先被警告。
凯文M 2010年

2

马丁的回答是好的,但有点含糊。该命令始终是派生和执行的,但是正常的shell行为是等待命令退出。“&”号将其放到后台,以便您返回终端提示,并可以执行其他操作。如果该进程将数据吐出到stdout或stderr,它将与您在提示符下所做的任何事情混在一起,并可能使您感到困惑。这就是为什么您使用>&/path/to/logfile.txt进行重定向。

响应George2,shell退出的正常行为是将SIGHUP信号发送到同一进程组中的所有进程(本质上是您生成的东西),它们通常会终止。如果即使关闭shell进程也希望继续执行此操作,则可以使用nohup命令使它们忽略此信号并继续运行。这种类型的进程有一个特殊的名称,称为守护进程(发音为“ demon”)。


谢谢Rich!假设我使用ssh终端登录计算机,然后使用ssh的终端执行命令(假设是一个长期运行的进程),然后如果我退出终端会话,那么该命令的长期运行将被正确终止吗?而且,即使退出外壳程序,我也希望命令继续执行,我应该使用nohup或&(在命令末尾)还是同时使用nohup和&?又为什么呢
George2 2010年

乔治,抱歉,我这么晚才回复。是的,如果您退出外壳程序,则长期运行过程将终止。如果您希望它继续运行,则需要同时执行nohup(不要在外壳关闭时终止它)和&(放置在后台,以便您可以Crtl-D或退出您的外壳)。您还可以查看setsid命令,该命令将使您的进程运行,让它以略有不同的方式忽略SIGHUP。
Rich Homolka 2010年

很好的答案,介绍了后台运行Shell启动进程的最佳实践。
Marcel Valdez Orozco '10
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.