Scripting 在KSH中通过SSH进行循环的更有效的方法?

Scripting 在KSH中通过SSH进行循环的更有效的方法?,scripting,ssh,ksh,Scripting,Ssh,Ksh,我目前在脚本中有以下代码行: set -A ARRAY OPTION1 OPTION2 OPTION3 OPTION4 set -A matches for OPTION in ${ARRAY[@]}; do DIFF=$(ssh $USER@$host " diff $PERSONALCONF $PRESETS$OPTION" ) if [[ $DIFF == "" ]];

我目前在脚本中有以下代码行:

set -A ARRAY OPTION1 OPTION2 OPTION3 OPTION4
          set -A matches

          for  OPTION in  ${ARRAY[@]}; do
                  DIFF=$(ssh $USER@$host  " diff $PERSONALCONF $PRESETS$OPTION" )
                  if [[ $DIFF == "" ]]; then
                          set -A matches"${matches[@]}" $OPTION
                  fi
          done
基本上,我有一个循环,通过预定义数组中的每个元素,连接到远程服务器(每次都是同一台服务器),然后使用diff命令将文件与循环定义的文件进行比较。基本上,它将personal.conf文件与personal.conf.option1、personal.conf.option2等进行比较。如果没有区别,则将其添加到数组中。如果有差异,什么也不会发生

我想知道是否可以通过SSH只连接一次来执行此操作或获得相同的结果(将匹配的文件存储在主机上的阵列中,而不是连接到的服务器上)。我不能在远程服务器上存储任何内容,也不能在该服务器上执行远程脚本。我只能通过ssh(一种愚蠢的设置)发出命令。目前,它连接的次数与有选项的次数相同。这似乎效率低下。如果有人有更好的解决办法,我很乐意听到

几个选项:

  • 您可以使用OpenSSH多路复用功能(请参阅
    ssh(1)

  • 而且,大多数shell都会乐意接受一个脚本来运行stdin,所以您可以运行类似于

    cat script.sh | ssh $HOST /bin/sh
    
  • 大多数脚本语言(Perl、Python、Ruby等)都有一些允许连接重用的SSH模块:

    #!/usr/bin/perl
    use Net::OpenSSH;
    my ($user, $host) = (...);
    my @options = (...);
    my @matches;
    my $ssh = Net::OpenSSH->new("$user\@$host");  
    for my $option (@options) {
        my $diff = $ssh->capture("diff $personal_conf $presets$option");
        if ($ssh->error) {
            warn "command failed: " . $ssh->error;
        }
        else {
            push @matches, $option if $diff eq '';
        }
    }
    print "@matches\n";
    

最后,我使用第二个选项将单独的脚本传输到/bin/ksh。它工作得很好!我喜欢第三个选项的lok,但不幸的是,我使用的是solaris设备,没有OpenSSH支持。请注意确保它真正运行阵列中的每个选项。根据我的经验,如果没有在ssh调用的末尾添加