【问题标题】:Bash scripting with heredocs or better approach使用 heredocs 或更好的方法编写 Bash 脚本
【发布时间】:2019-12-10 18:54:28
【问题描述】:

我需要在里面运行一些命令

ssh->ssh->clientprogram->loop command

这是我执行命令的要求。

  1. 将输入参数发送到第一个 ssh 服务器,捕获该命令的输出(这是一个 bash 脚本,相互依赖于同一路径中的其他脚本,并且在 $path 变量中可用。我确实检查了 echo $PATH)
  2. ip 的 step1 命令输出提供给第二个 ssh 命令。
  3. 在循环内循环 n 次,启用客户端并执行一系列命令并捕获两个命令的输出并验证第二个命令的输出(例如:一系列命令是:rm 文件;ls -> 检查该文件是否存在,然后重复相同直到 n 次迭代)
  4. Step3 应根据选择执行(例如:创建文件或删除文件)。这个变量应该是用户一开始的选项。

到目前为止,我能够放置所有静态 IP 并能够执行一个命令

 ssh_to_server () {

        remote_output=$(ssh -t root@10.25.55.10 << "EOF"
            # looking for command to capture output of input entry 1 and proceed further like
           command_output=$(/tmp/user/script $1) # this is not working. getting file or directory not found.
            ssh -t user@10.50.10.76 << "EOF1"
                clientprogram <<-"EOF2"
                  loop;then
                    command1  # based on "option"
                     command2  # checking if the delete or create operation is success.
                  end loop
                  /exit . # exit from the client program
                EOF2
            EOF1
    EOF)
    }
ssh_to_server "input" "option"

以上代码中的示例 IP。

我能够在客户端程序中执行命令并捕获输出,但我需要的是:

  1. 在第一个 ssh 服务器中捕获命令的 ip 输出并将其动态传递给第二个 ssh 服务器。
    1. 将选项从用户传递给客户端程序或第二个服务器以创建或删除文件。

注意:第二个 ssh 服务器不允许来自除第一个服务器之外的任何其他 ip 的 ssh。因此,ssh 隧道和其他隧道将不起作用。如果有更好的方法来处理使用其他脚本语言(Python、Perl)或Java(我可以创建一个jar)是可以接受的。

【问题讨论】:

  • = 周围不应该有空格,应该是command_output=$(/tmp/user/script $1)
  • 查看使用代理命令运行 ssh。这是处理ssh跳转主机的正常方式。
  • 另外,关于不工作的部分。您希望在哪个主机上运行/tmp/user/script?在您的本地主机上还是在跳转主机上?
  • 在第一台主机上
  • Inian,我修正了命令输出和命令之间的空格。

标签: python bash ssh heredoc


【解决方案1】:

有两个独立的传输

执行此操作的简单方法是两个单独的步骤,如下所示:

printf -v args_q '%q ' "$@"  # store our script's arguments in a string
host2_ip=$(ssh host1 get_host2_ip)
ssh -o"ProxyJump host1" "$host2_ip" "bash -s $args_q" <<'EOF'
  ...inner command for host2 goes here...
EOF

由于-o"ProxyJump host1",与host2_ip 的连接是从host1 建立的;但是,host2_ip 会返回给首先运行脚本的系统。


单次运输

如果您需要更高的性能,那么 ControlSocket 功能就派上用场了。

printf -v args_q '%q ' "$@"  # store our script's arguments in a string
ssh_common_args=( -o"ControlMaster=yes" -o"ControlPath $HOME/.ssh/socket-%r@%h:%p" )
host2_ip=$(ssh "${ssh_common_args[@]}" host1 get_host2_ip)
ssh "${ssh_common_args[@]}" -o"ProxyJump host1" "$host2_ip" "bash -s $args_q" <<'EOF'
  ...inner command for host2 goes here...
EOF

这样,host1 上的两个通道调用使用相同的连接——第一个连接用于检索 host2 IP 地址,第二个连接用于运行您的实际远程命令.

【讨论】:

  • 但是第二台主机只接受来自第一台主机的 ssh。这是否适用于这种情况。另外,我如何处理客户端程序中命令的输出。比如过滤第一个命令的输出并决定执行其他命令。
  • 至于捕获内容,这就是命令替换的用途——参见host2_ip=$(...)?这会将名为 host2_ip 的变量中的内容放回主机上,您可以在其中检查和修改它。
  • 您可以类似地在最后一个命令上使用host2_result=$(ssh ... 捕获较大命令的输出;在 EOF 之后的单独一行中添加结束 )
  • 我尝试使用您的 2 步脚本,这样我就可以获取第二个主机 IP,当我尝试使用第二个命令时,它会抛出我的权限被拒绝,并带有 msg“权限被拒绝(公钥)。”。你能告诉我可能是什么问题吗?补充一下,我没有第二台服务器的密钥,因为它是一个锁定的服务器,只允许来自服务器或主机 1。请让我知道您是否清楚,否则我会尝试解释更多。
  • 嗯。如果您有权登录主机 1,并且主机 1 包含主机 2 的明文密钥,则您拥有窃取该密钥并将其复制回您的原始系统所需的所有访问权限,除非host1 正在做一些非常聪明的事情(比如运行一个锁定的本地 SSH 代理)。
猜你喜欢
  • 2011-01-27
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2013-09-29
  • 2011-01-23
  • 1970-01-01
相关资源
最近更新 更多