패턴이 왜“명령 || 사실”유용합니까?


79

현재 데비안 패키지를 탐색 중이며 일부 코드 샘플을 읽었습니다. 예를 들어 postinst스크립트는 패턴입니다.

some command || true
another command || true

따라서 일부 명령이 실패하면 행이 true를 반환하지만 이것이 프로그램 출력에 어떤 영향을 미치는지 알 수 없습니다.


5
참고로, ||:이 (작성의 또 다른 관용적 방법 :을 가리키는 내장 테이블의 다른 항목되고 true있지만 - 보장 도 다시 Bourne 씨에 내장을로, POSIX 쉬에 대해 말했다 true마찬가지로 내장이 보장된다 - 그래서입니다 원격으로 고른 시간에 효율성보다 더 간결함).
Charles Duffy

답변:


151

이 패턴의 이유는 데비안 패키지의 관리자 스크립트가로 시작하는 경향이 있기 set -e때문에 모든 명령 (엄격히 말해서, 파이프 라인, 목록 또는 복합 명령)이 0이 아닌 상태로 종료되는 즉시 쉘이 종료됩니다. 이렇게하면 오류가 누적되지 않습니다. 문제가 발생하면 스크립트가 중단됩니다.

스크립트의 명령이 실패 할 수있는 경우 추가 || true하면 결과 복합 명령이 항상 상태 0으로 종료되므로 스크립트가 중단되지 않습니다. 예를 들어, 디렉토리를 제거해도 치명적인 오류가되어서는 안됩니다 (패키지가 제거되는 것을 방지). 그래서 우리는 사용합니다

rmdir ... || true

이후이 rmdir오류를 무시하도록 지시 할 수있는 옵션이 없습니다.


4
글쎄요, set -e전혀 필요가 없습니다 || true, 나는 문맥을 제공하는 것이 중요하다고 생각했습니다. POWER에서 이상한 점을 발견하면 버그 ( reportbug) 를 제출하는 것이 좋습니다 .
Stephen Kitt

16
@MichaelFelt는 실제로 set -e"데비안 규칙"일뿐만 아니라 항상 좋은 프로그래밍 패턴을 사용해야합니다. 보다. 예 : davidpashley.com/articles/writing-robust-shell-scripts
kay

2
여기 질문에 따라-왜 || trueset -e를 사용 하는가 가 문맥이며 가장 일반적 일 것입니다. 나는이 대답에 절한다! 말 그대로, 종료 상태가 관련이없는 것으로 간주되고 언제든지 기사 링크가 추가됨에 따라 스크립트 제어의 일부로 종료 상태를 사용하지 않는 것이 유용합니다. 유틸리티 ( set -e)를 볼 수 있지만 기사가 설명하는 한 "작성하는 모든 스크립트는 맨 위에 set -e를 포함해야합니다"라고 말하지 않습니다. 프로그래밍 스타일입니다. "항상 | 모든"에는 자체 트랩 세트 (일명-절대 값 다시 포함)가 포함됩니다. 와일드 카드 솔루션은 ALWAYS결국 일명 역효과를 낳습니다.
Michael Felt

1
@Kay 그것은 현재 대중적인 관점이지만 궁극적으로 스크립트의 이식성을 제한하는 수많은 가정에 빠져 있습니다. set -e행동 과 역사적 불일치가 있습니다. 유일한 대상이 bash있고 다른 비교적 최근에 사는 쉘 이라면 중요하지 않을 수 /bin/sh있지만 오래된 쉘 / 시스템을 지원하려는 경우 상황이 더 미묘합니다.
mtraceur

2
@StephenKitt 물론입니다. Sven Mascheck의 다양한 쉘 set -e동작을 설명 하는 매우 철저한 페이지가 있지만이 페이지에는 오늘날 관련이없는 많은 역사적 / 고대 쉘도 설명되어 있습니다. : 좁은 현대 초점이 두 페이지 ( "-e 설정"에 대한 검색)도있다 "lintsh"페이지 , > 내장 매크로 서브 페이지의 제한 - autoconf를 휴대용 쉘 문서
mtraceur

32

프로그램의 출력에는 영향을 미치지 않지만 방금 실행하면 호출자가 모든 논리가 미래 논리에 영향을 미치는 것처럼 진행할 수 있습니다.

답장 : 이전 명령 의 오류 상태 를 숨 깁니다 .

michael@x071:[/usr/sbin]cat /tmp/false.sh
#!/bin/sh
false

michael@x071:[/usr/sbin]cat /tmp/true.sh 
#!/bin/sh
false || true

michael@x071:[/usr/sbin]sh /tmp/false.sh; echo $?
1
michael@x071:[/usr/sbin]sh /tmp/true.sh; echo $? 
0

6
그것은 사실이지만 명령의 종료 상태를 마스킹하는 것이 유용한 이유에 대한 답은 아닙니다.
moopet

4
set -e는 0이 아닌 리턴시 스크립트가 즉시 종료됨을 의미합니다. 현지화 된 장소에서는 그런 일이 일어나기를 원하지 않을 수도 있습니다!
rackandboneman

저는 단순한 사람입니다. 그리고 오류 상태를 숨기는 유일한 이유는 "중도"이기 때문입니다. set -e는 신경 쓰지 않으면 오류가 발생합니다. 토론을 스크립트를 디버깅하고 오류에 응답하는 추가 논리를 작성하는 데 도움이되는 좋은 방법으로보고 있기 때문에 토론이 마음에 듭니다 (예 : || print- "xxx zeros non-zero here"). 쉘 함수 'fatal'이 있고 "뭔가 || 치명적인"행복하지 않다 "라는 메시지가 있습니다. imho 스크립트는 실패한 상태를보고해야합니다. 그렇지 않은 경우 오류가 없습니다
Michael Felt

내가 스스로에게 물어봐야 할 것은 : || true-코딩 버팀목 (현재 처리하고 싶지 않은 오류를 극복 / 붙여 넣을 수있는 게으른 방법; 디버그 도구 (-e이지만 || 아니오) 또는 좋은 코딩 실습에 대한 누군가의 교리. - 나는 기능으로 볼 - 잠재적 인 이익과 나는 한마디로 모두를 치료하는 마법의 지팡이로 표시되지 않습니다 -. 아름다움은 보는 사람의 눈 속에있는 것처럼 -. set -e|| true유틸리티는 특성과의 목표에 의해 정의됩니다 프로그래머는.
마이클 펠트

6
@MichaelFelt 고려 : git remote remove foo || true git remote add foo http://blah-리모컨이 존재하지 않으면 오류를 무시하고 싶습니다.
immibis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.