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