true && echo foo
인쇄됩니다foo
.false && echo foo
인쇄되지 않습니다foo
.bash -c "exit $a" && echo foo
foo
에 따라 인쇄됩니다$a
.
마지막 것을 작성하는 더 우아한 방법이 있습니까? 종료 값을 설정하기 위해 쉘을 시작해야 하는 것은 다소 번거로운 것 같습니다. 나는 다음과 같은 것을 생각하고 있습니다 :
return $a && echo foo
exit $a && echo foo
단, return
기능에서만 작동하며 절대 실행 exit
되지 echo foo
않습니다.
이 경우 우아함이란 다음을 의미합니다.
- 이해하기 쉬운
- 가지고 다닐 수 있는
- 읽기 쉬운
- 쓰기 쉽다
- 기억하기 쉽다
- 짧은
- 고성능
true
예를 들어 종료 코드를 매개변수(문서화된 기능)로 사용 하면 매우 우아할 것입니다 .
그렇다면 좀 더 우아한 방법이 있을까요?
배경
사용할 수 있는 곳 중 하나는 다음과 같습니다.
$ parallel 'setexitval {= $_%=3 =} || echo $?' ::: 0 1 2 3
Kosalonanda의 버전이 아마도 최고일 것입니다. 무슨 일이 일어났는지는 분명해요. 글이 길지도 않고 번거롭지도 않습니다. 기억하기 쉽고 휴대하기 쉽습니다. 유일한 단점은 다른 쉘을 분기한다는 것입니다(~0.5ms 소요).
$ parallel '(exit {= $_%=3 =}) || echo $?' ::: 0 1 2 3
또 다른 상황은 오류 상황을 시뮬레이션하려는 경우입니다. 예를 들어, 다양한 종료 코드를 설정하는 장기 실행 프로그램이 있고 다양한 종료 코드에 반응하는 일부 코드를 작성하고 있다고 가정해 보겠습니다. (exit $a)
장기 실행 프로그램을 실행하지 않고도 이를 사용하여 조건을 시뮬레이션할 수 있습니다 .
답변1
글쎄, return
그것은 함수에서 작동하므로 하나 만들어 보겠습니다.
$ ret() { return "${1-0}"; }
$ ret 1 || echo foo
foo
$ ret 123 ; echo $?
123
서브셸보다 더 많은 설정이 필요하지만 나중에 사용하기가 더 짧고 서브셸을 분기할 필요가 없습니다.
답변2
지정된 값으로 종료되는 서브쉘을 사용하십시오.
그러면 다음이 출력됩니다 5
.
a=5; ( exit $a ) && echo foo; echo $?
foo
그러면 다음 과 같이 인쇄됩니다 0
(이 0은 하위 쉘이 echo
아니라 후속으로 설정 됩니다).exit
a=0; ( exit $a ) && echo foo; echo $?
a
(명백한 설정 이나 명시적인 조사 없이) 축약된 형식으로 $?
:
( exit $a ) && echo foo
내 대답은 질문을 액면 그대로 받아들이고 "설정 방법 $?
(편리한 표기법 사용)"에 대한 재미있는 퀴즈로 해결하는 것입니다. 이 경우에는 더 깊은 의미, 기능 또는 맥락(아무것도 제공되지 않으므로)을 찾으려고 노력하지 않습니다. 또한 솔루션의 효과, 효율성 또는 유용성을 판단하지도 않습니다. 가끔 나는 대답할 때 "...하지만 그렇게 하지 마세요..."라고 말한 다음 "대신 이렇게 하세요..."라고 말합니다. 이 경우에는 질문을 간단한 호기심 퀴즈로 해석하기로 선택했습니다.
이제 질문에 더 많은 배경 정보가 추가되었습니다.
서브셸 분기 문제에 대한 나의 견해는 GNU와 같은 스크립트가 configure
수행할 수 있다는 것입니다.항상, 매우 빡빡한(장기 실행) 루프에서 수행되지 않는 한 그다지 느리지 않습니다.
parallel
저는 GNU 소프트웨어를 자주 사용하는 사람이 아니기 때문에 GNU에서 GNU를 사용하는 것에 대해 많이 이야기할 수 없습니다 .
답변3
대안(더 빠를 수도 있지만 더 우아하지는 않음):
test "$a" -eq 0 && echo foo
실행되지만 echo
종료 값을 로 설정하지 않으므로 $a
평범한 솔루션입니다.
답변4
가정을 확인해 보겠습니다.
true && echo foo
foo를 인쇄합니다. AND 연산자의 왼쪽 연관성&&
으로 인해 단락 논리 AND가 따르기 때문에 가장 왼쪽 명령이 성공적인 종료 상태 0(항상 해당 )을 반환하는 경우 해당 연산자의 가장 오른쪽 명령입니다. 실행됩니다.&&
||
true
false && echo foo
foo는 위에서 설명한 것과 정반대로 인쇄되지 않습니다.bash -c "exit $a" && echo foo
$a
foo는 본질적으로 잘못된$a
제어 가정 에 따라 인쇄됩니다&&
.&&
AND 논리이므로 성공 또는 실패라는 두 가지 상태만 인식합니다. 여기서 실패는 0보다 큰 종료 상태입니다 . 그러므로exit 1
andexit 2
and -는exit 3
;와 아무 관련이 없습니다.&&
실패는 가치에 관계없이 실패$a
이므로echo foo
실행되지 않습니다.
그래서 대답은아니요, 더 이상 우아한 방법은 없습니다그럼에도 불구하고 잘못된 가정 하에서 작동하는 작업을 수행하십시오. 그러나 명령을 통해 종료 상태를 설정하는 것이 목적이라면 Kusalananda의 답변에서 제안하는 서브 쉘을 사용하는 것으로 충분합니다. 개인적으로 나는 bash -c
서브쉘이 별도의 프로세스가 아닌 하위 프로세스/포크 프로세스로 구현될 수 있다는 점을 제외하면 부분적인 것과 다르지 않다고 생각합니다 . 사용자 는 $?
변수를 통해 설정해서는 안 됩니다. 변수는 명령의 성공 또는 실패를 전달하는 데 사용됩니다.
$a
잠시 초점을 바꿔 보겠습니다. 왜 설정하고 직접 확인할 수 있는지 $?
? 속하지 않는 값, 즉 에 값을 배치하는 것은 의미가 없습니다. 나는 "우아함"(그게 무엇을 의미하든)에서 "논리"와 "작업"으로 초점을 옮기는 것을 제안합니다.echo foo
$a
$a
$?
자, 게임을 해보자. 그것으로부터 영감을 얻으세요일카츄의 답변. 그러나 이 접근 방식을 사용하면 에코 조건부 실행을 강제할 필요가 없습니다. 제공된 변수가 성공을 나타내는 경우에만 에코되며 return
실행을 방지합니다.
$ thing(){ [ "${1-0}" -eq 0 ] || return "$1" ; echo "foo"; }
$ thing
foo
$ thing 0
foo
$ thing 1
$ echo $?
1
$ thing 2
$ echo $?
2
분명하지 않은 것은 당신이 할 수 있다는 것입니다thing $a