저는 Linux 셸의 초보자이지만 이 명령이 하위 셸을 생성한다는 것을 알고 있습니다.
서브쉘은 일반적으로 서브쉘 연산자나 대괄호(), 백틱` 또는 $() 구문과 같은 명령을 사용하여 생성됩니다.
: ${FOO:=$([ "$BAR" = "baz" ] && echo "true" || echo "false" )}
예를 들어 루프(여기서는 그렇지 않습니다) 하지만 나는 그것을 피하는 방법을 배우는 것을 좋아합니다. 일반적으로 위 과제에서 서브쉘을 피하기 위해 다음을 사용할 수 있습니까?
if [ -z "$FOO" ]; then
if [ "$BAR" = "baz" ]; then
FOO=true
else
FOO=false
fi
fi
답변1
일반적으로 위 과제에서 서브쉘을 피하기 위해 다음을 사용할 수 있습니까?
if [ -z "$FOO" ]; then if [ "$BAR" = "baz" ]; then FOO=true else FOO=false fi fi
네, 이렇게 쓰는 것이 맞습니다.
: ${FOO:=$([ "$BAR" = "baz" ] && echo "true" || echo "false" )}
서브셸을 실행하는 것(대부분의 셸에서는 비용이 많이 드는 프로세스 포크가 포함됨)도 여러 가지 이유로 잘못되었습니다.
- 확장명은
${FOO...}
인용되지 않았으므로 분할+글로브의 영향을 받아 최소한 DoS 취약점이 됩니다(이는 제공된 예 중 하나입니다).bash/POSIX 쉘에서 변수를 인용하는 것을 잊어버리는 보안 위험). echo "false"
[
echo true
또는 실패할 경우 실행하고, 실패할 경우에만 실행하기를 원합니다 . 적절하게 교체할 수 없습니다.[
a && b || c
if a; then b; else c; fi
ksh93 셸에서는 다음을 통해 서브셸과 이러한 문제를 방지할 수 있습니다.
: "${FOO:=${
if [ "$VAR" = baz ]; then
echo true
else
echo false
fi
}}"
그러나 이는 위의 표준적이고 분명한 설명에 if
비해 이점이 거의 없습니다 .
답변2
신비한 한 줄짜리의 경우 서브쉘 없이도 원하는 결과를 얻을 수 있다고 생각합니다.
[[ "$BAR" = "baz" ]] && FOO=${FOO-true} || FOO=${FOO-false}
하지만 난 선택할 거야if....