【问题标题】:Shell script can read file line by line but not perform actions for each lineShell 脚本可以逐行读取文件,但不能对每一行执行操作
【发布时间】:2021-05-31 04:31:29
【问题描述】:

我正在尝试在多台机器上运行此命令

sshpass -p 'nico' ssh -o 'StrictHostKeyChecking=no' nico@x.x.x.x "mkdir test"

IP 存储在以下 .txt 文件中

$ cat ips.txt
10.0.2.15
10.0.2.5

我创建了一个 bash 脚本,它逐行读取这个文件。如果我用echo 运行它:

#!/bin/bash
input="ips.txt"
while IFS= read -r line
do
  echo "$line"
  #sshpass -p 'nico' ssh -o 'StrictHostKeyChecking=no' nico@$line "mkdir test"
done < "$input"

它打印每一行:

$ ./variables.sh
10.0.2.15
10.0.2.5

这让我明白脚本正在按预期工作。但是,当我将 echo 行替换为我想为每一行运行的命令时:

#!/bin/bash
    input="ips.txt"
    while IFS= read -r line
    do
      #echo "$line"
      sshpass -p 'nico' ssh -o 'StrictHostKeyChecking=no' nico@$line "mkdir test"
    done < "$input"

它只对文件的第一个 IP 执行操作,然后停止。为什么?

【问题讨论】:

    标签: shell sshpass


    【解决方案1】:

    设法通过使用for 而不是while 来解决这个问题。脚本最终看起来像这样:

    for file in $(cat ips.txt)
    do
      sshpass -p 'nico' ssh -o 'StrictHostKeyChecking=no' nico@$file "mkdir test"
    done
    

    【讨论】:

      【解决方案2】:

      虽然您的示例是一个有效的解决方案,但这不是解释。

      你可以在这里找到解释:ssh breaks out of while-loop in bash

      两句话:

      1. “while”循环继续从循环头中定义的相同文件描述符(在您的情况下为 $input )读取
      2. ssh(或 sshpass)从标准输入(但在您的情况下从文件描述符 $input)读取数据。这是隐藏内容的关键,因为我们没有执行“ssh”来读取数据。

      只是为了理解问题,您可能会有同样奇怪的体验,例如在 while 循环中使用“ffmpeg”或“mplayer”等命令。 Mplayer 和 ffmpeg 在运行时使用键盘,因此它们会消耗所有文件描述符。

      又一个好笑的例子:

      #!/bin/bash
      
      {
        echo first
        for ((i=0; i < 16384; i++)); do echo "testing"; done
        echo "second"
      } > test_file
      
      while IFS= read -r line
      do
        echo "Read $line"
        cat | uptime > /dev/null
      done < test_file
      

      在第一部分我们写第一行:first 16384 行:测试 然后最后一行:第二个

      16384 行“测试”等于 128Kb 缓冲区

      在第二部分,命令“cat | uptime”将消耗 128Kb 缓冲区,所以我们的脚本会给出

      Read first
      Read second
      

      作为解决方案,正如您所做的那样,我们可以使用“for”循环。 或者使用“ssh -n” 或者使用一些文件描述符 - 你可以在我提供的链接中找到示例。

      【讨论】:

        猜你喜欢
        • 2013-06-08
        • 1970-01-01
        • 2021-06-02
        • 1970-01-01
        • 2015-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多