Более эффективный способ зацикливания на SSH в KSH? - PullRequest
2 голосов
/ 30 июня 2011

В настоящее время у меня есть следующие строки кода в сценарии:

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 (глупая установка).В настоящее время он подключается столько раз, сколько есть вариантов.Это кажется неэффективным.Если у кого-то есть лучшее решение, я бы с удовольствием его услышал.

1 Ответ

3 голосов
/ 30 июня 2011

Несколько вариантов:

  • Вы можете использовать функцию мультиплексирования OpenSSH (см. ssh(1)).

  • Кроме того, большинство оболочек с радостью примутскрипт для запуска через стандартный ввод, так что вы можете просто запустить что-то вроде

    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";
    
...