
次のコマンドは、リモートファイルが存在するかどうかに応じて終了ステータスを返します。
ssh $userAtServer "ls $targetDir/$targetFile" > $sshOutputFile
lsReturnValue=$?
その後、何かをテストできます。時々停止(10または20)し、追加のコード実行を防ぎます。
したがって、次のようにsshコマンドを実行してls関数の終了値を取得する必要があります。
(ssh $userAtServer "ls $targetDir/$targetFile" > $sshOutputFile ; lsReturnValue=$?) &
timeOutProcess $!
ただし、lsReturnValueは常に空の文字列を返します。
timeOutProcess は、コマンドが長すぎる場合にコマンドを終了する関数です。
timeOutProcess() {
processId=$1
#from http://www.bashcookbook.com/bashinfo/source/bash-4.0/examples/scripts/timeout3
timeout=45
interval=2
delay=5
(
((t = timeout))
while ((t > 0)); do
sleep $interval
kill -0 $processId || return 0
((t -= interval))
done
# Be nice, post SIGTERM first.
# The 'exit 0' below will be executed if any preceeding command fails.
kill -s SIGTERM $processId && kill -0 $processId || exit 0
sleep $delay
kill -s SIGKILL $processId
) 2> /dev/null
}
$を取得する方法を知りたいです。 sshコマンドの価値は何ですか?
答え1
標準シェル機能を使用して、プロセスを同期的に実行するか、組み込み関数を呼び出すssh
2つの方法でプロセスの戻り状態を取得できます。wait
走るとき
(ssh $userAtServer "ls $targetDir/$targetFile" > $sshOutputFile ; lsReturnValue=$?) &
これはlsReturnValue
子シェルにのみ設定され、親シェルの戻り状態以外の情報は取得できません。したがって、exit $lsReturnValue
サブシェルで実行し、親シェルからサブシェルの戻り状態を取得する必要があります。これにより、バックグラウンドプロセス全体がssh $userAtServer "ls $targetDir/$targetFile" > $sshOutputFile &
何でも簡単になります。
コマンドのタイムアウトを許可するシェルのフラグメントは戻り状態を維持しないため、それほど良いフラグメントではありません。 Linuxでは、以下を使用します。timeout
便利です。
ユーティリティがなければ、timeout
状況は少し難しくなります。 2つのサブプロセスを実行する必要があります。 1つは関心のあるプロセス、もう1つはsleep
タイムアウト部分に対して実行されるプロセスです。両方のプロセスのいずれかが返された場合は、別のプロセスを終了し、シェルが引き続き実行されるようにする必要があります。残念ながら、wait
引数なしで呼び出されると、組み込みプロセスはすべての子プロセスが終了するのを待ちます。 2つのプロセスを同期させる1つの方法は、両方ともパイプに書き込んで、一部のデータがパイプに表示されると終了するようにすることです。
lsReturnValue=$(
{
{ ssh $userAtServer "ls $targetDir/$targetFile" > $sshOutputFile
echo $?; } &
{ sleep 5; echo timeout; } &
} | head -n 1)
if [ "$lsReturnValue" = "timeout" ]; then …
複数のサーバーにコマンドを送信する場合は、次のことを真剣に検討してください。SSHマルチサーバーフレームワークたとえば、mussh、Clustershなどがあります。
答え2
SSHセッションで実行されているプロセスによって開かれたすべてのIOが正しく閉じられるまで、OpenSSH機能によってSSHセッションが閉じられないため、コマンドが中断されることがあります。
これを防止する1つの方法は、STDINとSTDOUTを端末以外の場所にリダイレクトすることです。
ssh $userAtServer "ls $targetDir/$targetFile > /dev/null < /dev/null 2>&1"
# lsReturnValue=$?
コマンドのSTDOUT / STDERRが必要な場合は、それをファイルにリダイレクトして後でcatすることができます。
ssh $userAtServer "ls $targetDir/$targetFile > /tmp/ls_output < /dev/null 2>&1;cat /tmp/ls_output"