`

`

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

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

有什么<&-作用?
我的猜测是它与< /dev/null

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

  1. 正在后台运行的作业和正在退出的脚本——有什么冲突吗?
  2. 当终端关闭时,所有从终端接受 stdin 的进程都会关闭吗?

答案1

<&-不是相当与 相同的事情< /dev/null<&-关闭 fd 0,而< /dev/null从 device 重定向它/dev/null,它从不提供任何数据,并且总是在读取时给出 EOF。区别主要在于,read(2)来自关闭 FD(本<&-例)的调用将出现 EBADF 错误,而来自空重定向 FD 的调用将不返回读取的字节(文件结束条件)。如果您的程序从不从标准输入读取数据,那么区别并不重要。

如果您要在后台运行某些内容,则关闭 FD 是一个很好的做法,因为如果后台进程尝试从 TTY 读取任何内容,它就会挂起。不过,这个例子并没有完全处理它应该处理的所有事情;理想情况下,在某个地方会有一个nohuporsetsid调用,以完全解除后台进程的关联。

答案2

man bash

  [n]<&word

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

答案3

<&-关闭标准输入。

一般形式,由 POSIX 定义, 是:

[n]<&word

其创建文件描述符的目的n是由 表示的文件描述符的副本word。如果n省略,则假定为标准 in ,如果word-,则文件描述符n将被关闭。

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

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

您可以在远程计算机上运行该命令,而无需将其附加到 ssh 会话,方法是使用屏幕或者多路复用器:

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

相关内容