Экспорт PATH с использованием NET::SSH:PERL

Я пишу сценарий оболочки для автоматизации некоторых утомительных задач, которые мы выполняем. Мне нужно ssh на сервер и удаленно изменить переменную PATH, чтобы эта переменная сохранялась для выполнения следующих команд. Код ниже;

sub ab_tier{
 my $ssh=Net::SSH::Perl->new($host);
 $ssh->login($user2,$user2);
 my $PATH;
 my($stdout,$stderr,$exit)=$ssh->cmd("export
 PATH=/usr/bin/sudo:/local/perl-5.6.1/bin:$PATH");
 my($PATH, $stderr, $exit)=$ssh->cmd("echo $PATH");
 print $PATH; # Check the path for correctness : does not change 
}

Однако ПУТЬ не меняется. Есть ли другой способ реализовать это или я делаю что-то не так? Мне нужно автоматизировать задачи, так что не думайте, что здесь поможет $ssh->shell. Пожалуйста, предложите.


Я внес изменения в соответствии с предложениями, и все работает отлично. Однако я заметил еще одну проблему, которая возникает при попытке отображения переменных среды.

  my $cmd_ref_pri={
    cmd0=>"echo $ENV{'HOME'}",
    cmd1=>"chmod 777 $ENV{'COMMON_TOP'}/temp"
  };

Теперь я подключаюсь к удаленному серверу, используя Net::SSH::Perl, и значение, возвращаемое $ENV{"HOME"}, является значением моего домашнего каталога, а не удаленного сервера. Однако, если я добавлю команду как в:

    my $cmd_ref_pri={
       cmd0=>"whoami ; echo $ENV{'HOME'}",
       cmd1=>"chmod 777 $ENV{'COMMON_TOP'}/temp"
     };

Затем отображается идентификатор пользователя пользователя, который использует ssh для удаленного сервера. У меня не установлены другие модули, а доступен только Net:SSh:perl, поэтому я вынужден использовать это.

рутина для выполнения команды

    sub ssh_cmd{
       #$cmd_sub - contains command, $ssh contains object ref
       my ($cmd_sub,$ssh)=@_;
       my($stdout, $stderr, $exit)=$ssh->cmd("bash",$cmd_sub);
       if( $exit !=0){
       print $stdout;
       print  "ERROR-> $stderr";
       exit 1;
     }
    return 0;
   }

Любые предложения относительно того, почему это могло произойти?

3 ответа

Решение

cmd() не передает ваши команды в одну оболочку. Он выполняет их в отдельных оболочках (или без какой-либо оболочки - руководство не ясно об этом). Как только вы закончите export PATH оболочка завершается, и новый PATH теряется.

Похоже, можно передать все соответствующие команды одному процессу оболочки в виде отдельных строк в $ stdin?

my $stdin='export A=B
echo $A
';
$ssh->cmd("bash",$stdin);

Это будет работать так же, как при интерактивном входе в систему (но без управления терминалом, поэтому команды, которые общаются напрямую с терминалом, скорее всего, потерпят неудачу).

В любом случае Net::SSH::Perl не выглядит лучшим инструментом для работы. Я бы предпочел использовать expect для автоматизации.

Установите PATH при каждом вызове команды:

$ssh->cmd('PATH=/usr/bin/sudo:/local/perl-5.6.1/bin:$PATH echo $PATH');

И BTW, Net::SSH::Perl больше не поддерживается, в настоящее время Net::SSH2 и Net::OpenSSH являются лучшими альтернативами.

Запишите команды в удаленный временный файл, затем выполните его. Или пропустите элемент $PATH и используйте полный путь для последующих команд (при условии, что вы это знаете).

Другие вопросы по тегам