명령 대체에 설정된 액세스 변수

명령 대체에 설정된 액세스 변수

간단한 스크립트를 작성했습니다

 #!/bin/bash -x
 selentry=`ls -l / | sort ; ts=${PIPESTATUS[0]}`
 echo $ts

그러나 $ts에는 아무것도 표시되지 않습니다. $ts 변수를 어떻게 표시합니까, 아니면 변수의 명령에서 종료 상태 코드를 어떻게 얻습니까?

selentry=`ls -l / | sort`

답변1

존재하다:

selentry=`ls -l / | sort ; ts=${PIPESTATUS[0]}`

더 현대적인 것과 동일합니다.

selentry=$(ls -l / | sort ; ts=${PIPESTATUS[0]})

의 코드는 서브쉘 환경에서 실행됩니다( $(...)쉘 외부의 다른 쉘 프로세스에서도 실행됨). 따라서 이 하위 쉘의 변수를 수정해도 상위 쉘에는 영향을 미치지 않습니다.bashksh93

이 작업을 수행할 때:

var=$(cmd)

그러나 종료 상태는 cmd에서 사용할 수 있습니다 $?. 이는 $PIPESTATUS다음 상황 에는 적용되지 않습니다 .

var=$(foo | bar)

하나의 값만 포함합니다(여기서 종료 상태가 되는 서브셸의 종료 코드 bar(해당 옵션이 켜져 있지 않은 경우 pipefail0이 아닌 경우 종료 상태가 될 수 있음).) 배열은 다음 위치에 있습니다. 할당 명령 Influence의 영향을 받지 않습니다.foozsh$pipestatus

그러나 여기서 (서브쉘의) 종료 상태에 관심이 없다면 sort다음과 같이 할 수 있습니다.

selentry=$(ls -l / | sort; exit "${PIPESTATUS[0]}")
ts=$?

여기서도 다음을 수행할 수 있습니다.

exec 3< <(ls -l /) # here ls is started as an asynchronous command
ls_pid=$!
selentry=$(sort <&3)
sort_status=$?
wait "$ls_pid"
exec 3<&- # close that fd 3
ls_status=$?

심지어:

{
  selentry=$(sort)
  sort_status=$?
  wait "$!"
  ls_status=$?
} < <(ls -l /)

변수 할당이 명령 대체 후에도 유지되도록 하는 보다 일반적인 문제와 관련하여 에서는 명령 대체 형식을 ksh93사용할 수 있습니다 (단, / 는 지원되지 않음 ).${ cmd;}ksh93$PIPESTATUS$pipestatus

var=${
  foo; c1=$?
  bar; c2=$?
}

Bourne과 유사한 다른 쉘에는 유사한 기능이 없으므로 다른 수단(예: 임시 파일)을 통해 데이터를 전달해야 합니다.

var=$(
  foo; echo "c1=$?" > "$tempfile"
  bar; echo "c2=$?" >> "$tempfile"
)
. "$tempfile"

아니면 여기:

selentry=$(
  ls -l / | sort
  typeset -p PIPESTATUS | sed '1s/PIPESTATUS/my_&/' > "$tempfile"
}
. "$tempfile"
ls_status=${my_PIPESTATUS[0]}

관련 정보