【问题标题】:Execute several commands through ssh with local and remote values通过 ssh 使用本地和远程值执行多个命令
【发布时间】:2014-06-18 21:29:21
【问题描述】:

我正在编写一个脚本来匹配本地值和远程值。到目前为止,我的代码可以正常运行,看起来像这样:

#!bin/bash

MY_ARRAY=('value1' 'value2' 'value3' 'wrongValue)
for VALUE in "${MY_ARRAY[@]}"
do
    if [[ $VALUE =~ ^v ]] ; then
        echo "$VALUE : $(ssh admin@machine matching_function $VALUE)" >> output.file
    else
        echo "$VALUE : this is a wrong value" >> output.file
    fi
done

唯一的问题是,对于循环的每次迭代,它都会创建并关闭一个新的 ssh 连接。由于我原来的数据集比较大,执行起来需要很长时间。

我正在寻找一种优化方法,并阅读了有关使用 ssh admin@machine <<EOF 将多行命令传递给 ssh 并修改了我的代码:

MY_ARRAY=('value1' 'value2' 'value3' 'wrongValue)
ssh admin@machine << EOF
    for VALUE in "${MY_ARRAY[@]}"
    do
        if [[ $VALUE =~ ^v ]] ; then
            echo "$VALUE : $(matching_function $VALUE)" >> output.file
        else
            echo "$VALUE : this is a wrong value" >> output.file
        fi
    done
EOF

但是,它不起作用,我收到了几个错误:

  • Pseudo-terminal will not be allocated because stdin is not a terminal.。我怀疑这部分是由于我的远程 shell 受到限制,并且与 echo 冲突。

  • $MY_ARRAY 似乎在远程机器上未定位:

    -rbash: line 5: conditional binary operator expected -rbash: line 5: syntax error near unexpected token '^v' -rbash: line 5: ' if [[ =~ ^v ]] ; then'

我也不确定 bash 将如何区分 $VALUE(应该从我的本地计算机解释)和 matching_function(应该从远程计算机解释)

【问题讨论】:

  • 请在您的问题中包含“它不起作用”的证据。是否有任何错误信息,请也包括这些信息。否则你走在正确的轨道上。 &lt;&lt; HEREDOCS 内的 var sub 是标准的,而不会尝试在本地空间中执行该代码,因此您的 macthing_function 应该远程执行。
  • @shellter 我扩展了我的示例以指出我现在遇到的 2 个不同的错误
  • 进行小测试,让您了解ssh x@y.com '/bin/ls -l $VAL'ssh x@y.com "/bin/ls -ls $VAL" 之间的区别。然后将match_func 添加到组合中。任何在"..." 中工作的东西都将在&lt;&lt;HEREDOC 中工作,除非你调用像&lt;&lt;'HEREDOC' 这样的“硬”引用,这给你与..com '/bin/ls -l $VAL' 相同的行为。祝你好运。
  • @shellter 感谢您的提示。我已经使用了 ssh 引号,但在执行以下操作时仍然遇到问题:ssh x@y "VAL=\$(match_func arg1)。我不能将结果归因于局部变量,而是创建一个远程变量并将函数的结果分配给它(我尝试了其他语法来尝试获取此结果,但无济于事)
  • 那么您从ssh x@y "VAL=\$(match_func arg1); echo \${VAL}" 得到任何结果吗?更重要的是,再次回到小步骤的想法,当您执行ssh x@y "match_func StringArg" 时会发生什么?祝你好运!

标签: bash ssh heredoc


【解决方案1】:

man ssh:

如果指定了command,它将在远程主机上执行,而不是登录shell。

人们可能会告诉你,你可以通过使用不同数量的 -t 来强制分配一个伪 tty,这确实有效,但会带来运行登录 shell 的副作用,因此最好这样做

ssh admin@machine bash <<EOF
    ...
    #some instructions
    ...
EOF

而不是强制不执行登录shell。

【讨论】:

    【解决方案2】:

    即使已经有一段时间了,我也会用我解决问题时使用的解决方案来回答我的问题。

    在结合使用 heredocs 和 SSH 苦苦挣扎之后,我想出了一个部分解决方案:

    MY_ARRAY=('value1' 'value2' 'value3' 'wrongValue)
    ssh admin@machine -T << EOF >output.file
        for VALUE in "${MY_ARRAY[@]}"
        do
            if [[ \$VALUE =~ ^v ]] ; then
                echo "\$VALUE : \$(matching_function \$VALUE)"
            else
                echo "\$VALUE : this is a wrong value"
            fi
        done
    EOF
    

    我在局部变量之前使用了$,在远程变量之前使用了\$。这是由于heredoc 的行为,因为bash 在执行heredoc 的内容之前解释了$ 前面的每个变量。

    &gt;output.file 允许我捕获 ssh 命令的输出并进行一些后处理。但是,我从来没有发现如何从&lt;&lt;EOF ... EOF 中分配变量,但我想这更像是一个heredoc 问题。

    我现在会接受我的回答,但如果有人能澄清为什么/如果不可能将变量从 heredoc 分配到外部,我会很高兴。

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 2015-07-25
      • 2010-12-25
      • 2021-02-23
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 2013-11-22
      相关资源
      最近更新 更多