SSHを使用してサーバーAからサーバーBに接続し、他のユーザーを使用してコマンドを実行しようとしています。ただし、ログファイルからパターンを検索しようとすると、「ログファイルを開けません」というメッセージが表示されます。以下はサンプルコードです。
ssh -t user@hostname <<EOF
sudo su - someotheruser
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ $a -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
EOF
スクリプトを実行すると、次のように表示されます。unable to open "tail........."
サーバ B にログインしたままで複数のコマンドを実行することはできません。
答え1
各コマンドが実行されるタイミング、実行される場所、受信される入力を慎重に検討してください。
- ここからドキュメントを展開して始めましょう。これは
tail
、/パイプラインが変数置換と同様にawk
localhostで実行されることを意味します。$a
- その後、
ssh
コマンドを実行します。ここから拡張文書を受け取ります。これはリモートシェルで実行されるコマンドです。 - リモートシェルは引数なしで実行されるため、標準入力から実行するコマンドを読み取ります。これらのコマンドにはが含まれますが、
sudo
(シェルに応じて)次の行の一部を含めることもできます。 - リモートシェルの実行。まず、そのユーザーのコマンドを読み込んで実行し、次に標準入力からコマンドを読み取る
sudo su - someotheruser
シェルを実行します。標準入力には、最初のリモートシェルから読み取られていないコンテンツが含まれているため、あまり予測できません(シェルと入力パイプから読み取られる量によって異なります)。someotheruser
.profile
- 実行中のシェルは、
someotheruser
読み取ったコマンド(存在する場合)を実行します。 - 実行中のシェルは、コマンドを読み取った後にコマンドを
someuser
実行します。if
ここでドキュメントの拡張を防ぐには、heredoc タグの周りに引用符を使用します。標準入力の不適切な混合を防ぐために、sh -c …
2番目のリモートシェルから受信した入力を使用または指定します。
ssh -t user@hostname <<'SSH_EOF'
sudo su - someotheruser <<'SU_EOF'
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
SU_EOF
SSH_EOF
ソースコードが本当に必要someotheruser
ですか.profile
?そうでない場合はを使用しsudo -u someotheruser
てください。その場合は、sudo -i -u someotheruser
sudoers ルールを適切に調整します。
ログファイルを読むことは、高い権限を必要とする唯一の作業tail
ですsomeotheruser
。
ssh -t user@hostname <<'SSH_EOF'
a=`sudo -u someotheruser tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
SSH_EOF
特権の上昇方法を混ぜないと、人生ははるかに簡単になります。sudo
スイッチsomeuser
を使用する代わりにsomeotheruser
SSHを使用してlocalhostに接続します。 2つのSSHコマンドを接続するのは簡単です。キー設定 - 特定のコマンドのみを実行できるようにするキーを設定することもできます(たとえば、アカウントを介したtail -10 /somepath/application.log
SSH.ssh/config
のエイリアスの定義)someuser
。
Host hostname-someotheruser
HostName hostname
UserName someotheruser
ProxyCommand ssh someuser@hostname
その後実行
a=$(ssh hostname-someotheruser tail -10 /somepath/application.log |
awk '/Agent Exited/ { print $3 }')
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
答え2
Ifステートメントはコマンドではなく、シェルで解釈する必要があります。これを試してみてください。ローカルスクリプトの作成
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
[ $a -eq 0 ] && echo "Success" || echo "Faiilure"
bash シェルを呼び出してこれらのコマンドを実行します。
ssh -t user@hostname 'echo "pass" | sudo -Sv && bash -s' < script.sh
答え3
あなたの説明で見ると、2つの問題があると思います。まず、そうする必要はありません<
。マニュアルページによると、ssh
ホスト名の後に続く文字列は、リモートで実行されるコマンドとしてすぐに認識されます。複数のコマンドを実行するには、すべてのコマンドを一重引用符で囲まれた文字列に入れることができます。この文字列はリモートで送信され、スクリプトのように実行されます。
ssh -t user@hostname 'tail -10 /somepath/application.log | awk \'/Agent Exited/ { print $3 }\'; if [ $a -eq 0 ]; then echo "Success"; else echo "Failure"; fi'