SSH로 인해 while 루프가 중지됨


30

나는 마침내 몇 주 동안 어려움을 겪고있는 문제를 해결했습니다. "권한 키"와 함께 SSH를 사용하여 명령을 원격으로 실행합니다. while 루프에서 할 때를 제외하고는 모두 괜찮습니다. ssh 명령으로 반복을 완료하면 루프가 종료됩니다.

오랫동안 나는 이것이 일종의 ksh 기묘하다고 생각했지만 지금은 bash가 실제로 동일하게 작동한다는 것을 알았습니다.

문제를 재현하는 작은 샘플 프로그램. 이것은 스냅 샷을 생성하여 클러스터의 노드간에 복제하는 더 큰 구현에서 나온 것입니다.

#!/bin/bash

set -x

IDTAG=".*zone"
MARKER="mark-$(date +%Y.%m.%d.%H.%M.%S)"
REMOTE_HOST=sol10-target
ZFSPARENT=rpool

ssh $REMOTE_HOST zfs list -t filesystem -rHo name,mounted $ZFSPARENT | grep "/$IDTAG    " > /tmp/actionlist

#for RMT_FILESYSTEM in $(cat /tmp/actionlist)
cat /tmp/actionlist | while read RMT_FILESYSTEM ISMOUNTED
do
   echo ${RMT_FILESYSTEM}@${MARKER}
   [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
   echo Remote Command Return Code: $?
done

(zfs list "-H"옵션의 동작 정의에 따라 grep 검색 표현식에 TAB 문자가 있습니다.)

내 샘플에는 루트에 대한 ZFS 파일 시스템이 있습니다. 여기서 모든 "영역"은 다음과 같은 데이터 세트에 루트 파일 시스템이 있습니다.

풀 / 구역 / app1zone
풀 / 구역 / group2 / app2zone

기타

위의 루프는 선택한 각 데이터 세트에 대한 스냅 샷을 작성해야하지만 대신 첫 번째 데이터 세트에서만 작동 한 다음 종료됩니다.

프로그램에서 스크립트가 존재하면 "/ tmp / actionlist"파일을 확인하여 올바른 수의 데이터 세트를 쉽게 확인할 수 있습니다.

ssh 명령이 예를 들어 echo 명령으로 바뀌면 루프는 모든 입력 라인을 반복합니다. 또는 내가 좋아하는 것- "echo"를 문제의 명령 앞에 추가하십시오.

for 루프를 대신 사용하면 작동하지만 데이터 세트 목록의 잠재적 크기로 인해 최대 확장 명령 줄 길이에 문제가 발생할 수 있습니다.

ssh 명령이있는 루프 만 나에게 문제가 있음을 99.999 % 확신합니다!

ssh 명령이 실행되는 반복이 완료되었습니다. while 루프에 입력 된 데이터가 갑자기 손실되는 것처럼 보입니다. 처음 몇 개의 입력 행이 ssh 명령을 수행하지 않으면 실제로 SSH 명령을 실행할 때까지 루프가 계속됩니다.

필자가 테스트하고있는 랩탑에는 2 개 또는 3 개의 샘플 데이터 세트 만있는 2 개의 Solaris 10 VM이 있지만이 기능이 적용되는 대규모 SPARC 시스템에서도 마찬가지입니다. 많은 데이터 세트가 있습니다.


7
SSH가 표준 입력에서 읽는 중일 수 있습니다 actionlist. ssh의 표준 입력을/dev/null
BatchyX

나는 그것을 시도 할 것이다. ssh를 래퍼에 넣는 것이 도움이되지 않는다고 덧붙이고 싶습니다.
Johan

당신이 올바른지. 어떻게 볼 수 없습니까!?
Johan

@BatchyX 귀하의 의견이 답변이라고 생각합니다.
CVn

@BatchyX가 다시 게시 할 수 있다면 대답을 "수락"하고 싶습니다.
요한

답변:


43

SSH가 표준 입력에서 읽고 조치 목록을 읽었을 수 있습니다. ssh의 표준 입력을 / dev / null로 리디렉션하십시오.

ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER} </dev/null

일반적으로 while read스타일 루프에서 표준 입력을 방해 할 수있는 명령을 실행할 때 전체 루프 본문을 중괄호로 묶습니다.

cat /tmp/uuoc | while read RMT_FILESYSTEM ISMOUNTED
do {
    echo ${RMT_FILESYSTEM}@${MARKER}
    [ "$ISMOUNTED" = "yes" ] && ssh $REMOTE_HOST zfs snapshot -r ${RMT_FILESYSTEM}@${MARKER}
    echo Remote Command Return Code: $?
} < /dev/null; done

3
처음에는 중괄호를 구체적으로 사용하는 데 두 배가 좋습니다 ... 20 년 동안 스크립팅을 해본 적이 없었습니다 (적어도 기억할 수는 없습니다). FWIW (그리고 내 자신의 방어) 때때로 나는 가독성을 위해 예외를 만들고 여분의 고양이 진술을 추가합니다! 나는 갑자기 새로운 것을 다시 배우기 때문에이 포럼을 좋아합니다! 특히 나는이 경우와 같이 줄의 시작 부분에 리디렉션을 추가하고 싶지만 문제를 혼동하는 포럼에서는 유용한 응답이 적습니다!
Johan

{...}와 (...)의 차이점을 알아 내려고 노력했습니다. ksh 맨 페이지는 {...}이 명령 줄의 시작 부분에서만 인식되는 특수 키워드라고 말합니다. 그러나 또 다른 차이점이 있습니다 ... ( </tmp/file [ -z "$SOMEVAR" ] && awk '{print "X", $0}' )중괄호와 동일합니다. 나는 닫는 중괄호가 새로운 줄에 있어야한다는 사실이 아니라 생산 된 결과를 의미한다.
Johan

5
또한 OpenSSH의 ssh 에는 -n/ dev / null에서 stdin을 (효과적으로) 다시 여는 옵션이 있습니다.
Chris Johnsen 2013

sudo루프 내에서 명령과 함께 사용하기위한 해결 방법이 있습니까?
bonh

나는 나이부터 -n을 사용하고 어느 시점에서 습관을 잃어 버렸습니다 .... 그리고 이제는 파고
들었던
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.