【问题标题】:How to execute multiple commands on machineB from machineA efficiently?如何有效地从机器上执行机器上的多个命令?
【发布时间】:2015-04-17 17:05:28
【问题描述】:

我的 machineA 中有一个 tar (abc.tar.gz) 文件,我需要将其复制并解压到我的 machineB 中。在我的machineB 中,我有一个正在运行的应用程序,它是该 tar 文件的一部分,所以我需要编写 shell 脚本,通过在 machineA 上运行 shell 脚本来在 machineB 上执行以下操作 -

  • machineB 上执行命令sudo stop test_server
  • 删除 /opt/data/ 文件夹中的所有内容,留下该 tar 文件。
  • 将该 tar 文件复制到此位置 machineB/opt/data/
  • 现在解压 /opt/data/ 文件夹中的 tar 文件。
  • 现在执行这个命令sudo chown -R posture /opt/data
  • 之后执行此命令启动服务器sudo start test_server

machineA 中,我会将我的shell 脚本和tar 文件放在同一个位置。到目前为止,我已经通过阅读教程了解了 shell 脚本,因为我最近开始使用 shell 脚本。

#!/bin/bash
set -e

readonly SOFTWARE_INSTALL_LOCATION=/opt/data
readonly MACHINE_LOCATION=(machineB) # I  will have more machines here in future.
readonly TAR_FILE_NAME=abc.tar.gz

ssh david@${MACHINE_LOCATION[0]} 'sudo stop test_server'
ssh david@${MACHINE_LOCATION[0]} 'sudo rm -rf /opt/data/*'
sudo scp TAR_FILE_NAME david@${MACHINE_LOCATION[0]}:$SOFTWARE_INSTALL_LOCATION/
ssh david@${MACHINE_LOCATION[0]} 'tar -xvzf /opt/data/abc.tar.gz'
ssh david@${MACHINE_LOCATION[0]} 'sudo chown -R posture /opt/data'
ssh david@${MACHINE_LOCATION[0]} 'sudo start test_server'

我做对了,还是我们可以改进上述 shell 脚本中的任何内容?我需要在我们的生产机器上运行上面的 shell 脚本。

是否可以显示每个步骤的状态消息,说明此步骤已成功执行,因此转到下一步,否则会终止 shell 脚本并显示正确的错误消息?

【问题讨论】:

    标签: linux bash shell ssh scp


    【解决方案1】:

    您可以在一次 ssh 往返中完成所有操作,并且根本不需要将 tarball 存储在远程位置。

    #!/bin/bash
    set -e
    
    readonly SOFTWARE_INSTALL_LOCATION=/opt/data
    readonly MACHINE_LOCATION=(machineB)
    readonly TAR_FILE_NAME=abc.tar.gz
    
    ssh david@${MACHINE_LOCATION[0]} "
        set -e
        sudo stop test_server
        sudo rm -rf '$SOFTWARE_INSTALL_LOCATION'/*
        tar -C '$SOFTWARE_INSTALL_LOCATION' -x -v -z -f -
        sudo chown -R posture '$SOFTWARE_INSTALL_LOCATION'
        sudo start test_server" <"$TAR_FILE_NAME"
    

    这还修复了 tarball 将被提取到您的主目录(不是 /opt/data)并且您在变量 TAR_FILE_NAME 的插值上缺少美元符号的错误。

    我将远程脚本放在双引号中,以便您可以在脚本中使用$SOFTWARE_INSTALL_LOCATION;注意内插值是如何在远程 shell 的单引号中内插的(当然,如果值包含单引号,这将不起作用)。

    如果您可以直接以用户posture 的身份运行tar 命令,您或许可以避免使用chown

    添加echo 提示以显示进度是一项微不足道的练习。

    如果您将所有东西(sshsudo)都设置为无密码访问,事情会顺利得多,但我相信即使您确实收到一两个密码提示,这也应该有效。

    (如果您确实想远程存储压缩包,只需在tar 之前添加tee。)

    【讨论】:

    • 感谢您的帮助。现在看起来好多了。我不能以posture 用户身份运行这个shell 脚本,因为sudo stop test_serversudo start test_server 这两个命令我不能用posture 用户执行,因为我只能用david 用户执行所以这就是我这样做的原因。我知道我可以修改/etc/hosts 文件以添加由posture 用户运行的这两个命令,但问题是该文件将被puppet 覆盖,因为这是在生产中管理我们的系统。我希望你明白我想说什么。
    • 还有一件事,有没有什么方法可以让我在命令提示符下只输入一次密码,然后对所有命令重复使用相同的密码,而不是每次都输入密码?跨度>
    • 当然你不能以posture 运行root 命令,但也许你可以sudo -u posture tar zxvf ...
    • 不,我不知道修改/etc/hosts 将如何允许您以其他用户身份运行特权命令。也许你的意思是/etc/sudoers
    • sudo 默认情况下会记住您的密码几分钟。对于ssh,请考虑使用ssh-agent 和/或无密码密钥(不太推荐)。
    【解决方案2】:

    您可以使用 ssh 命令的退出状态为每个步骤生成状态消息,就像我尝试使用前两个 ssh 命令一样。

    #!/bin/bash
    set -e
    
    readonly SOFTWARE_INSTALL_LOCATION=/opt/data
    readonly MACHINE_LOCATION=(machineB) # I  will have more machines here in future.
    readonly TAR_FILE_NAME=abc.tar.gz
    
    
    # An error exit function
    
    function error_exit 
    {
      echo "$1" 1>&2
      exit 1
    }
    
    
    if ssh david@${MACHINE_LOCATION[0]} 'sudo stop test_server'; then 
    
    echo "`date -u`     INFO    : Stopping test_Server" 1>&2
    
    else
      error_exit "`date -u`     ERROR   : Unable Stop test_Server! Aborting."
    
    fi
    
    
    
    if ssh david@${MACHINE_LOCATION[0]} 'sudo rm -rf /opt/data/*'; then 
        echo "`date -u`     INFO    : Removing /opt/data" 1>&2
    else
        error_exit "`date -u`   ERROR   : Unable to remove! Aborting."
    
    fi
    
        sudo scp TAR_FILE_NAME david@${MACHINE_LOCATION[0]}:$SOFTWARE_INSTALL_LOCATION/
        ssh david@${MACHINE_LOCATION[0]} 'tar -xvzf /opt/data/abc.tar.gz'
        ssh david@${MACHINE_LOCATION[0]} 'sudo chown -R posture /opt/data'
        ssh david@${MACHINE_LOCATION[0]} 'sudo start test_server'
    

    密码管理可以创建 ssh 无密码认证。 http://www.linuxproblem.org/art_9.html

    【讨论】:

      猜你喜欢
      • 2018-05-14
      • 2012-04-06
      • 2011-07-13
      • 1970-01-01
      • 1970-01-01
      • 2012-07-27
      • 2015-01-19
      • 2015-11-27
      • 2011-04-06
      相关资源
      最近更新 更多