bashscript에서 읽기 전용 변수를 설정했습니다.
readonly NO_OUTPUT="1>/dev/null 2>&1"
내 스크립트의 일부 명령에서 이 변수를 사용할 때 ${NO_OUTPUT}이 목록에 있는 다른 파일이라고 생각하는 것과 같은 오류가 발생하는 이유는 무엇입니까?
예를 들어 다음이 있습니다.
make install ${MAKE_PREFIX} ${NO_OUTPUT}
마지막으로 다음 내용으로 오류가 생성됩니다. make: *** No rule to make target '1>/dev/null 2>&1'. Stop.
그러나 다음과 같이 변경하면:
make install ${MAKE_PREFIX} 1>/dev/null 2>&1
예상대로 정확히 작동합니까?
다른 명령(cp, rm 등)에서도 비슷한 문제가 발생했는데 오류가 발생했습니다.
답변1
make install ${MAKE_PREFIX} ${NO_OUTPUT}
호출 make
되면 install
분할+glob의 결과는 MAKE_PREFIX 변수의 내용에 적용되고, 분할+glob의 결과는 NO_OUTPUT 변수의 내용에 별도의 인수로 적용됩니다.
아마도 당신은 다음과 같은 것을 원할 것입니다:
if [ -n "$VERBOSE" ]; then
nooutput() { "$@"; }
else
nooutput() { "$@" > /dev/null 2>&1; }
fi
nooutput make install "$MAKE_PREFIX"
내용이 별도의 인수인 MAKE_PREFIX 변수를 make
호출 하는 데 사용되며 , 자세한 정보 표시 모드에서 실행되지 않는 경우 stdout 및 stderr이 /dev/null로 리디렉션됩니다.install
여기에서 별칭을 사용할 수도 있습니다.
if [ -n "$VERBOSE" ]; then
alias nooutput=' '
else
alias nooutput='> /dev/null 2>&1 '
fi
nooutput make install "$MAKE_PREFIX"
bash
POSIX가 아닌 모드에서 셸을 사용하는 경우에도 shopt -s expand_aliases
.
코드에서 별칭을 사용할 때도 별칭을 정의해야 합니다.읽다(아니요달리기).
에서는 zsh
다음을 수행할 수도 있습니다.글로벌별칭은 명령 위치에 있지 않아도 확장되므로 다음과 같이 할 수 있습니다.
if [ -n "$VERBOSE" ]; then
alias -g '$NOOUTPUT$='
else
alias -g '$NOOUTPUT$=> /dev/null 2>&1'
fi
make install "$MAKE_PREFIX" $NOOUTPUT$
$NOOUTPUT$
대신 여기서는 매개변수 확장이 발생하지 않았으며 null로 대체되거나 코드를 읽을 때 코드가 평가되기 훨씬 전에 대체된다는 $NOOUTPUT
점을 더 명확하게 하기 위해 여기에서 사용됩니다 .$NOOUTPUT$
> /dev/null 2>&1
답변2
쉘은 각 부분을 확장하기 전에 각 부분이 무엇인지 식별하기 위해 명령줄에서 각 단어(토큰, 부분)를 구분합니다. 리디렉션은 명령줄 구문 분석 단계 근처에 설정됩니다. 훨씬 나중에 변수 확장이하나리디렉션된 단어일 수 없습니다.
아니요, 배열 변수나 단순 변수도 작동하지 않습니다.
$ NO_OUTPUT=( "1>/dev/null" "2>&1" )
$ printf '%s\n' "${NO_OUTPUT[@]}"
1>/dev/null
2>&1
$ a="1>/dev/null"
$ b="2>&1"
$ printf '%s\n' "$a" "$b"
1>/dev/null
2>&1
$ printf '%s\n' 1>/dev/null 2>&1
$
따라서 아니요. 변수 내용을 쉘 단어 토큰으로 변환할 수 있는 방법이 없습니다.
와는 별개로 eval
. 그러나 eval은 일반적으로 evil
보안 위험이 있습니다.
답변3
eval
문자열을 받아 명령으로 실행하는 command를 사용하면 코드는 다음과 같아야 합니다.
eval make install ${MAKE_PREFIX} ${NO_OUTPUT}
이런 일이 발생하는 이유와 원하는 결과를 얻을 수 있는 더 나은 방법에 대해 알아보려면 다음을 살펴보세요.변수에 저장된 명령을 어떻게 실행할 수 있습니까?.