다음 명령은 원격 파일이 존재하는지 여부에 따라 종료 상태를 반환합니다.
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
호출하는 두 가지 방법으로 프로세스의 반환 상태를 가져올 수 있습니다 . wait
당신이 달릴 때
(ssh $userAtServer "ls $targetDir/$targetFile" > $sshOutputFile ; lsReturnValue=$?) &
이는 lsReturnValue
자식 셸에만 설정되며, 부모 셸의 반환 상태 외에는 어떤 정보도 얻을 수 없습니다. 따라서 exit $lsReturnValue
하위 쉘에서 실행하고 상위 쉘에서 하위 쉘의 반환 상태를 가져와야 합니다. 그러면 전체 백그라운드 프로세스가 ssh $userAtServer "ls $targetDir/$targetFile" > $sshOutputFile &
무엇이든 단순화될 수 있습니다.
명령의 시간 초과를 허용하는 셸 조각은 반환 상태를 유지하지 않기 때문에 그다지 좋은 조각이 아닙니다. Linux에서는 다음을 사용하십시오.timeout
유용.
유틸리티가 없으면 timeout
상황이 조금 더 까다로워집니다. 두 개의 하위 프로세스를 실행해야 합니다. 하나는 관심 있는 프로세스이고 다른 하나는 sleep
시간 초과 부분에 대해 실행되는 프로세스입니다. 두 프로세스 중 하나가 반환되면 다른 프로세스를 종료하고 셸이 계속 실행되도록 허용해야 합니다. 불행하게도 wait
인수 없이 호출하면 내장 프로세스는 모든 하위 프로세스가 종료될 때까지 기다립니다. 두 프로세스를 동기화하는 한 가지 방법은 둘 다 파이프에 쓰고 일부 데이터가 파이프에 나타날 때 종료하도록 하는 것입니다.
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 세션이 닫히지 않기 때문에 명령이 중단되는 경우가 있습니다.
이를 방지하는 한 가지 방법은 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"