【问题标题】:Bash for loop to execute commands on remote serversBash for 循环在远程服务器上执行命令
【发布时间】:2017-02-04 08:16:14
【问题描述】:

所以我有一个长度为 n 的服务器列表。我需要打开一个连接并编辑一个文件并关闭它。

这是我目前拥有的:

#!/bin/bash

server_list=(a b c d)

for i in "${server[@]}"; do ssh "${server[@]}"; cd /etc; cp file file.bak; perl -pi -i 's/find/replace/g' file; exit; done

我唯一的问题是我无法退出 ssh 连接并转到数组中的下一个。我使用了-n-t-T 选项无济于事。

谢谢。

【问题讨论】:

  • 您是否可以在远程机器上没有备份,在本地执行全局替换,只需执行scp file "${server[@]}/etc/"
  • 这里要理解的重要一点是ssh "${server[@]}" 是与cd /etc 不同的一个不同的命令,并且由于您的代码当前是编写的,cd /etc 不会是运行直到ssh "${server[@]}" 退出。

标签: linux bash ssh


【解决方案1】:

您当前的代码没有向ssh 会话发送任何命令。使用 heredoc 将您的命令传递给 ssh:

    #!/bin/bash

    server_list=(a b c d)
    for i in "${server_list[@]}"; do
      #
      # As per Charles' suggestion - "bash -s" makes sure the commands
      # would run with Bash rather than the default shell on the remote
      # server.
      #
      # I have left your commands exactly as in your question.
      # They can be written as a single command as per @chepner's recommendation 
      ssh "$i" bash -s << "EOF"
        cd /etc
        cp file file.bak
        perl -pi -i 's/find/replace/g' file
        exit
EOF
    done

【讨论】:

  • 你真的是想把除了 EOF(包括 shebang)之外的所有东西都放在页边空白处吗?我试图编辑,但认为你同时发生了一些事情,所以我们最终在那里互相跺脚。
  • @CharlesDuffy 那可能是我;我试图从ssh 中删除-n 选项,这会阻止读取heredoc。
  • 整个远程脚本可以简化为perl -pi.bak 's/find/replace/g' /etc/file,从而不需要使用heredoc。
  • 顺便说一句,我建议ssh "$i" "bash -s",所以你不依赖用户配置的默认解释器。我的意思是,据我们所知,他们可能会使用完全不合规的东西,比如鱼。
  • @CharlesDuffy 这是我认为可以忽略的细节,除非 OP 提出来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多