Bash 스크립트 리디렉션은 변수로 사용할 수 없습니다.

Bash 스크립트 리디렉션은 변수로 사용할 수 없습니다.

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"

bashPOSIX가 아닌 모드에서 셸을 사용하는 경우에도 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}

이런 일이 발생하는 이유와 원하는 결과를 얻을 수 있는 더 나은 방법에 대해 알아보려면 다음을 살펴보세요.변수에 저장된 명령을 어떻게 실행할 수 있습니까?.

관련 정보