성공할 때까지 bash에서 명령을 실행하는 방법


237

스크립트가 있는데 사용자에게 정보를 요청하고 싶습니다. 사용자가이 정보를 입력 할 때까지 스크립트를 계속할 수 없습니다. 다음은 이것을 달성하기 위해 명령을 루프에 넣으려는 시도이지만 어떤 이유로 작동하지 않습니다.

echo "Please change password"
while passwd
do
echo "Try again"
done

while 루프의 많은 변형을 시도했습니다.

while `passwd`
while [[ "`passwd`" -gt 0 ]]
while [ `passwd` -ne 0 ]]
# ... And much more

그러나 나는 그것을 작동시키지 못하는 것 같습니다.

답변:


403
until passwd
do
  echo "Try again"
done

또는

while ! passwd
do
  echo "Try again"
done

20
이 중 Ctrl-C를 사용하기가 어렵습니다.
DonGar

이것을 취소해야한다고 생각한다면, 쉘의 새 인스턴스 (예 : "bash"를 입력)를 열고 취소하려면 다른 터미널 창으로 가서 새로 생성 된 bash를 종료하십시오. 방법.
Ethan

50
Ctr-C를 사용하기 쉬운 방법 : until passwd; do echo "Try again"; sleep 2; done-2 초 이내에 Ctr-C를 누르면 echo작업이 완료됩니다.
Christian

9
@azmeuk : until passwd || (( count++ >= 5 )); do echo "foo"; done(bash 만, 변수가 존재하는 경우 count를 0으로 설정하십시오) 평범한 sh를 위해 이것을 필요로한다면, 몸의 카운터를 증가시키고 []
Justin Sane

2
이 페이지를 여러 번 참조한 후 명령을 재 시도하기 위해 일반 bash 함수를 작성하기로 결정했습니다. 여기는 다음과 같습니다. gist.github.com/felipou/6fbec22c4e04d3adfae5
felipou

94

$?대신 이전 명령의 종료 상태 인 테스트를 수행해야합니다 . passwd모든 것이 정상적으로 작동하면 0으로 종료하고 암호 변경에 실패한 경우 0이 아닌 값으로 종료됩니다 (잘못된 비밀번호, 비밀번호 불일치 등).

passwd
while [ $? -ne 0 ]; do
    passwd
done

당신의 역 따옴표 버전으로, 당신은 같은 물건이 될 것 passwd 파일의 출력을 비교하고 Enter password그리고 confirm password등을.


2
그렇지 $?않습니까?
Shawn Chin

나는 반대 상황에 적응하는 방법이 명확하기 때문에 이것을 좋아합니다. 예를 들어 실패 할 때까지 비 결정적 버그로 프로그램을 실행하십시오
Eric

성공이 0이 아닌 종료 코드로 표시되면 이것이 필요합니다.
Gudlaugur Egilsson

2
두 가지 버전을 유지하고 싶지 않은 길고 복잡한 명령이 passwd있는 /bin/false경우 첫 번째 항목 을 변경하여 약간 개선 할 수 있다고 생각합니다 .
coladict

허용되는 답변이어야합니다. 이것은 대부분의 쉘 (bash, mksh 및 ash에서 테스트)에서 작동하며 상황에 쉽게 적용 할 수 있습니다.
linuxandria

73

@Marc B의 답변을 자세히 설명하려면

$ passwd
$ while [ $? -ne 0 ]; do !!; done

명령에 맞지 않는 것과 같은 일을하는 좋은 방법입니다.


11
불행히도 나를 위해 작동하지 않습니다 ( '!!'명령을 찾을 수 없습니다). 어떻게 작동합니까?
Johannes Rudolph

2
이전 명령을 실행하는 것은 배쉬 트릭입니다. 예를 들어 sudo명령 앞에 쓰는 것을 잊어 버린 경우 sudo !!루트 권한으로 이전 명령을 실행하면됩니다.
JohnEye

1
내가 할 수있는 내 프로필에 스크립트를 만들 수 있습니다, 그래서 갈 수 있습니다 : $ makelastwork
user230910

2
달리기 사이에 잠자는 법?
Kamil Dziedzic

6

무한 루프를 사용하여이를 달성 할 수 있습니다.

while true
do
  read -p "Enter password" passwd
  case "$passwd" in
    <some good condition> ) break;;
  esac
done

2
이것은 여러 줄 명령을 함수에 넣을 필요가없는 유일한 대답입니다. 내가 그랬어 && break내 검증 명령하지만 대신 선택하는 경우 이후에.
carlin.scott

4

재시도 제한을 원하는 사람이있는 경우 :

max_retry=5
counter=0
until $command
do
   sleep 1
   [[ counter -eq $max_retry ]] && echo "Failed!" && exit 1
   echo "Trying again. Try #$counter"
   ((counter++))
done

1
until $(command)기본적으로 항상 잘못되었습니다. until command대신 사용하십시오 . 는 $(...)원인 출력 의를 command자체가 명령으로 실행할 수, 그리고 종료 상태 가 보조 명령은 루프가 실행하거나 실패하기로 결정 무엇을 할; 명령 대체가 존재할 때 명령 자체의 종료 상태가 고려되는 stdout 없는 경우에만 해당됩니다 .
Charles Duffy

$command문자열을 사용하여 명령을 저장하는 것이 본질적으로 신뢰할 수없는 이유에 대해서는 BashFAQ # 50 을 참조하십시오 . 여전히 이것은 이전보다 낫습니다. 공감 철회.
Charles Duffy

3
while [ -n $(passwd) ]; do
        echo "Try again";
done;

3
이것은 그것을하는 방법이 아닙니다 ... 당신은 psswd의 stdout을 부정하고 그에 대한 단항 테스트를하고 있습니다. @duckworthd가 좋습니다.
Ray Foss

또한 인용하지 있기 때문에, 시험이 때 무례한 행동을하는 것입니다 입니다 출력 만 개 이상의 단어, 또는 그 경기의 현재 디렉토리에있는 파일 또는 등등 글로브의 표현이다.
Charles Duffy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.