`<&-`是做什么的?


20

我将Bash的一个片段复制到远程执行的ssh命令的后台:

ssh user@remote <<CMD
some process <&- >log 2>error &
CMD

怎么<&-办?
我的猜测是,它与< /dev/null

我的下一个理解是,三个主要的文件描述符(stdinstdoutstderr)需要被关闭,以防止:

  1. 作业正在后台运行,脚本正在退出-发生冲突吗?
  2. 当终端关闭时,正在接受来自终端的stdin的所有进程都关闭了吗?

强制性交叉引用:请参阅外壳程序的控制和重定向运算符是什么?—尽管关于此运算符的唯一说明是它“可用于关闭或复制文件描述符”,并且您应“参见Shell手册的相关部分”。
G-Man说'恢复莫妮卡'

如果我没记错的话,ssh -nNT user@remote 'command'将创建一个非交互式的SSH会话。追加&到它的背景,前置nohupcommand以保持它,如果你的连接模运行。
Mark K Cowan

1
@MarkKCowan man ssh建议-N完全禁用运行远程命令,而快速测试支持此功能。
汤姆·亨特

是的,我使用-nNTR进行反向端口转发。然后忽略-N和-R :)
Mark K Cowan

Answers:


30

<&-与... 不太一样< /dev/null<&-关闭fd 0,而< /dev/null将其从device重定向,该设备/dev/null从不提供任何数据,并且始终在读取时提供EOF。区别主要在于,read(2)从封闭FD(<&-情况)发出的调用将因EBADF而出错,而从以null重定向的FD进行的调用将不返回读取的字节(文件结束条件)。如果您的程序从不从stdin读取,则区别并不重要。

如果您要对某事进行后台处理,则关闭FD是一个好习惯,因为如果后台进程试图从TTY中读取任何内容,则该进程将挂起。但是,此示例并未完全处理应有的一切;理想情况下,某个位置会有一个nohupsetsid调用,以完全取消后台进程的关联。


因此nohup,除了关闭文件描述符外,我还应该使用?
埃里克·弗朗西斯

2
最彻底的方法(模仿程序守护自己的方式)类似于setsid some process <&- >path/to/log 2>path/to/error。更快的方法类似于nohup some process &
汤姆·亨特

2
@EricFrancis:nohup在这里使用没有意义。nohup防止进程HUP在其控制端子关闭时接收信号。但是在这种情况下,您没有任何终端。
cuonglm

@TomHunt:后台进程没有挂起,而ssh会话挂了。
cuonglm

2
关闭fds 0、1和2不是一个好主意...您不希望创建的下一个fd占用这些值之一。最好将它们重定向到/ dev / null
Murray Jensen 2015年

7

man bash

  [n]<&word

用于复制输入文件描述符。如果word扩展为一个或多个数字,则用表示的文件描述符n将成为该文件描述符的副本。如果输入的数字 word 未指定打开的文件描述符供输入,则发生重定向错误。如果word计算为-n则关闭文件描述符。如果n未指定,则使用标准输入(文件描述符0)。


正确的定义是,当您拥有[n]<&word且单词包含多个数字时,未指定会发生什么。
schily 2015年

你什么意思?是man bash错的吗?
埃里克·弗朗西斯

@EricFrancis因为在标准中未指定,所以bash选择以合理的方式(对于“合理”的某些适当定义)实施它。其他壳可能会也可能不会。
muru

@muru问题被标记了bash,没有posix-shell
Barmar 2015年

@Barmar好的。所以...?
muru

7

<&- 关闭标准输入。

POSIX定义一般形式为:

[n]<&word

制作文件描述符的目的n是用表示的文件描述符的副本word。假设如果n省略了标准输入,如果word-n则将关闭文件描述符。

它与并不相同</dev/null,因为在的情况下</dev/null,标准输入仍处于打开状态,并已重定向到其他地方。

您需要关闭ssh套接字附带的进程的所有文件描述符,否则ssh会话无法关闭。

您可以使用screentmux在远程计算机上运行命令而无需将其附加到ssh会话:

ssh user@remote 'screen -S test -d -m command'

为什么要投反对票?
cuonglm
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.