1

私は、実行する面倒​​なタスクのいくつかを自動化するためのシェルスクリプトを書いています。サーバーに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 
}

ただし、PATHは変更されません。これを実装する別の方法はありますか、それとも私は何か間違ったことをしていますか?タスクを自動化する必要があるので、$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"
     };

次に、表示されるユーザーIDは、リモートサーバーに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;
   }

なぜこれが起こる可能性があるのか​​についての提案はありますか?

4

3 に答える 3

1

cmd()コマンドを1つのシェルに渡していない。それらを別々のシェルで実行します(またはシェルなしで-マニュアルはそれについて明確ではありません)。終了するとすぐにexport PATHシェルが終了し、新しいPATHが失われます。

関連するすべてのコマンドを$stdinの個別の行として単一のシェルプロセスに渡すことができるように見えますか?

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

これは、対話型ログインの場合と同じように機能します(ただし、端末制御がないため、端末と直接通信するコマンドは失敗する可能性があります)。

とにかくNet::SSH::Perlはその仕事に最適なツールのようには見えません。私はむしろexpect自動化に使用したいと思います。

于 2012-01-04T11:09:07.333 に答える
1

すべてのコマンド呼び出しでPATHを設定します。

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

そしてところで、Net :: SSH :: Perlはもう保守されていません。現在、Net::SSH2Net::OpenSSHがより良い代替手段です。

于 2012-01-04T16:18:30.307 に答える
0

コマンドをリモートの一時ファイルに書き込んでから、そのファイルを実行します。または、$ PATHをスキップして、後続のコマンドにフルパスを使用します(知っている場合)。

于 2012-01-04T11:18:31.633 に答える