跟进使用 while 循环 ssh 到多个服务器,即 for
while IFS= read -r -u9 HOST ; do ssh "$HOST" "uname -a" ; done 9< servers.txt
它从不同的文件描述符 ( 9
) 读取,
如何让它从不同文件描述符的管道中读取?
如果我的管道命令是,写入第 9 个文件描述符grep
的最简单方法是什么?通过管道传输第 9 个文件描述符的语法是什么?grep
跟进使用 while 循环 ssh 到多个服务器,即 for
while IFS= read -r -u9 HOST ; do ssh "$HOST" "uname -a" ; done 9< servers.txt
它从不同的文件描述符 ( 9
) 读取,
如何让它从不同文件描述符的管道中读取?
如果我的管道命令是,写入第 9 个文件描述符grep
的最简单方法是什么?通过管道传输第 9 个文件描述符的语法是什么?grep
如果您的意思是希望
while IFS= read -ru9 line; do ...; done
循环遍历 的输出grep
而不是 的内容servers.txt
,那么使用 bash、zsh 或 ksh93 的最新版本,您可以使用进程替换的重定向而不是管道:grep
将以其 stdout 重定向到管道的写入端运行,并将<(...)
替换为打开后的文件路径(此处使用常规输入重定向在 fd 9 上)将指向同一管道的读取端。根据系统和/或 shell,这将是命名管道或/dev/fd/<a-number>
类似的管道(例如/proc/self/fd/<a-number>
)。可移植地(在任何类似 POSIX 的 shell 中),您可以执行以下操作:
即使用常规管道,但进行一些 fd 改组,以便将在管道读取端打开的 fd 移动到 fd 9,并使用临时 fd 3 将 fd 0 恢复到原始 stdin。
请注意,在某些 shell 中,包括 bash(除非
lastpipe
启用该选项并且 shell 不是交互式的),循环while
将在子 shell 中运行。除了
read
fd 9 之外,您还可以简单地我们
ssh
再次使用 fd 3 重定向技巧将 的 stdin 恢复到管道外的原始标准输入。while
在 GNU 系统上,您可以使用as 来代替循环xargs
:servers.txt
要从每行一个列表中获取列表,并且:从 的输出中获取它
grep
。您还可以添加一些
-P0
并行运行所有这些,或-P4
并行运行最多 4 个(但在任何一种情况下都共享相同的标准输入)。另一个好处是,如果其中一个
ssh
失败,它将反映在整体退出状态中。除了使用 之外
grep
,您还可以在循环中进行 shell 模式匹配:(标准
sh
语法并且不在子 shell 中运行)。1 ksh 是在 80 年代中期引入进程替换的 shell,但直到最近,您还无法从那里重定向 fd。