Bash: 상태를 설정하는 우아한 방법이요? [폐쇄]

Bash: 상태를 설정하는 우아한 방법이요? [폐쇄]
  • true && echo foo인쇄됩니다 foo.
  • false && echo foo인쇄되지 않습니다 foo.
  • bash -c "exit $a" && echo foofoo에 따라 인쇄됩니다 $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 foofoo를 인쇄합니다. AND 연산자의 왼쪽 연관성 &&으로 인해 단락 논리 AND가 따르기 때문에 가장 왼쪽 명령이 성공적인 종료 상태 0(항상 해당 )을 반환하는 경우 해당 연산자의 가장 오른쪽 명령입니다. 실행됩니다.&&||true

  • false && echo foofoo는 위에서 설명한 것과 정반대로 인쇄되지 않습니다.

  • bash -c "exit $a" && echo foo$afoo는 본질적으로 잘못된 $a제어 가정 에 따라 인쇄됩니다 &&. && AND 논리이므로 성공 또는 실패라는 두 가지 상태만 인식합니다. 여기서 실패는 0보다 큰 종료 상태입니다 . 그러므로 exit 1and exit 2and -는 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

관련 정보