Eri*_*cis 20 shell bash io-redirection
我复制了一段 Bash 到后台远程执行的 ssh 命令:
ssh user@remote <<CMD
some process <&- >log 2>error &
CMD
Run Code Online (Sandbox Code Playgroud)
有什么作用<&-
?
我的猜测是它与< /dev/null
我的下一个理解是需要关闭三个主要文件描述符(stdin
, stdout
, stderr
)以防止:
Tom*_*unt 30
<&-
是不是很一样的东西< /dev/null
。<&-
关闭 fd 0,而< /dev/null
从设备重定向它/dev/null
,它从不提供任何数据并且总是在读取时提供 EOF。不同之处主要在于read(2)
来自关闭的 FD(<&-
案例)的调用将使用 EBADF 出错,而来自空重定向的 FD 的调用将不返回读取的字节(文件结束条件)。如果您的程序从不从 stdin 读取,则区别无关紧要。
如果您正在后台处理某些内容,关闭 FD 是一种很好的做法,因为如果后台进程尝试从 TTY 读取任何内容,它就会挂起。然而,这个例子并没有完全处理它应该做的一切;理想情况下,在某处会有一个nohup
orsetsid
调用,以完全分离后台进程。
见man bash
:
Run Code Online (Sandbox Code Playgroud)[n]<&word
用于复制输入文件描述符。如果
word
扩展为一个或多个数字,则由 表示的文件描述符n
将成为该文件描述符的副本。如果 中的数字word
未指定为输入打开的文件描述符,则会发生重定向错误。如果 word 的计算结果为-
,n
则关闭文件描述符。如果n
未指定,则使用标准输入(文件描述符 0)。
<&-
关闭标准输入。
[n]<&word
Run Code Online (Sandbox Code Playgroud)
其制作文件描述符的目的n
是由word
. 假设标准如果n
被省略,如果word
是-
,文件描述符n
将被关闭。
它与 不同</dev/null
,因为在 的情况下</dev/null
,标准输入仍然打开,并被重定向到其他地方。
您需要关闭所有附加到 ssh 套接字的进程的文件描述符,否则无法关闭 ssh 会话。
您可以使用screen或tmux在远程机器上运行该命令,而无需将其附加到 ssh 会话:
ssh user@remote 'screen -S test -d -m command'
Run Code Online (Sandbox Code Playgroud)