【问题标题】:More efficient way of looping over SSH in KSH?在 KSH 中循环 SSH 的更有效方式?
【发布时间】:2011-09-25 22:12:11
【问题描述】:

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

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 发出命令(有点愚蠢的设置)。目前,它连接的次数与选项一样多。这似乎效率低下。如果有人有更好的解决方案,我很想听听。

【问题讨论】:

  • 注意确保它真正运行数组中的每个选项。如果您不将

标签: scripting ssh ksh


【解决方案1】:

几个选项:

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

  • 另外,大多数 shell 会很乐意接受一个在标准输入上运行的脚本,所以你可以运行类似的东西

    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 支持。
猜你喜欢
  • 2016-04-14
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
相关资源
最近更新 更多