공백과 와일드카드가 포함된 매개변수 전달 문제

공백과 와일드카드가 포함된 매개변수 전달 문제

매개변수에 와일드카드 및/또는 공백이 포함된 경우(해당 매개변수가 선택사항인 경우) 매개변수를 전달하는 데 문제가 있습니다. 이것은 매우 추상적으로 들리므로 간단한 예를 들어보겠습니다. 다음 쉘 스크립트에는 some_command.sh2개 또는 3개의 매개변수가 필요합니다. 첫 번째 인수는 명령줄 스위치여야 하고, 두 번째 인수는 선택 사항이며, 있는 경우 형식의 명령줄 스위치여야 하며 --NAME=VALUE, 마지막 인수는 필수이며 무엇이든 될 수 있습니다.

#!/bin/bash
# This is file some_command.sh
# Synopsis:
# some_command.sh --switch1=val1 [--switch2=val2] arg
echo "switch1: $1"
shift
if [[ "$1" == --*=* ]]
then
  echo "switch2 ($1) detected"
  shift
fi
echo argument is ${1:?argument missing}

some_command.sh다음과 같은 다른 스크립트를 통해 호출한다고 가정해 보겠습니다 caller.sh.

#!/bin/bash
# This is file caller.sh
if [[ ${1:-x} == x ]]
then
  switch="--abc=long argument"
else
  switch=""
fi
some_command.sh "--exclude=*~" "$switch" arg

인용을 참고하시기 바랍니다. 따옴표는 --exclude쉘에서 와일드카드 표현식을 확장할 수 없기 때문에 필요하고 "$switch"공백 $switch이 있는 텍스트가 포함될 수 있으며 인수를 공백으로 분할할 수 없기 때문에 필요합니다.

의도는 우리가 실행하면 caller.sh x다음과 같은 결과가 발생해야 한다는 것입니다.

some_command.sh "--exclude=*~" "--abc=long argument"  arg

예를 들어 우리가 실행하면 caller.sh y다음과 같아야 합니다.

some_command.sh "--exclude=*~" arg

내가 caller.sh여기서 제공하는 것은 실제로아니요후자의 경우 실행되기 때문에 잘 작동합니다.

some_command.sh "--exclude*~" "" arg

이것은 정확하지 않습니다.

명령 앞에 접두어를 붙여 보았습니다 eval. 이렇게 하면 문제가 해결되지만 $switch주변 따옴표도 제거되고 "--exclude"와일드카드는 셸에서 평가됩니다.

eval계속해서 추가 인용 수준(예: )을 사용할 수 있을 것 같지만 "\"--exclude*~\""이는 나쁜 해결책입니다. 누구든지 이 작업을 수행하는 더 깨끗한 방법이 있는지 궁금합니다.

내가 왜 이 질문을 하는지 궁금하다면: zip파일 이름의 공백을 처리해야 하는 스크립트를 작성하는 동안 우연히 이 질문을 발견했습니다.

그런데 위에서 언급한 것처럼 bash및 에서 문제가 발생합니다 zsh. 나는 또한 쉘 중 하나만 작동하는 영리한 솔루션에도 관심이 있습니다.

답변1

배열은 가변 개수의 인수로 확장되므로 사용하십시오.

#! /bin/bash -
# This is file caller.bash
switch=()
if [[ ${1-x} == x ]]
then
  switch=("--abc=long argument")
fi
some_command.sh "--exclude=*~" "${switch[@]}" arg

또는 다음 구문을 사용할 수 있습니다 ${var+...}.

#! /bin/sh -
# This is file caller.sh
unset switch
if [ "${1-x}" = x ]
then
  switch="--abc=long argument"
fi
some_command.sh "--exclude=*~" ${switch+"$switch"} arg

zsh를 사용하면 다음을 수행할 수 있습니다.

#! /bin/zsh -
switch=
if [ "${1-x}" = x ]
then
  switch="--abc=long argument"
fi
some_command.sh "--exclude=*~" $switch arg

zsh하지 마세요분할+전역매개변수 확장에서는 그렇지 않습니다.빈 제거이것이 당신이 원하는 것입니다.

관련 정보