공백이 포함된 옵션/인수/매개변수를 스크립트에서 함수로 전달

공백이 포함된 옵션/인수/매개변수를 스크립트에서 함수로 전달

모두 안녕하세요. 미리 감사드립니다.

내 상황에 대해 포럼을 검색했지만 해결책을 찾을 수 없습니다. 명령줄에서 인수/옵션/매개 변수를 전달하는 스크립트가 있습니다. 값 중 하나에 공백이 있는데, 이를 큰따옴표로 묶었습니다. 예를 들어 설명하는 것이 더 쉬울 수도 있습니다. 인수/옵션/매개변수 사용을 용서해 주세요.

$:  ./test1.ksh -n -b -d "Home Videos"

내 문제는 변수를 "홈 비디오"로 설정하고 함께 사용하는 것입니다. 내 예에서 -d는 디렉토리를 지정하는 것입니다. 모든 디렉토리에 공백이 있는 것은 아니지만 일부 디렉토리에는 공백이 있습니다.

이것은 예상대로 작동하지 않는 코드의 예입니다.

#!/bin/ksh

Function1()
{
echo "Number of Args in Function1: $#"
echo "Function1 Args: $@"
SetArgs $*
}

SetArgs()
{
echo -e "\nNumber of Args in SetArgs: $#"
echo "SetArgs Args: $@"
while [ $# -gt 0 ]
do
  case $1 in
    -[dD])
    shift
    export DirectoryName=$1
    ;;
    -[nN])
    export Var1=No
    shift
    ;;
    -[bB])
    export Var2=Backup
    shift
    ;;
    *)
    shift
    ;;
  esac
done
Function2
}

Function2()
{
echo "Directory Name: ${DirectoryName}"
}

Function1 $*

이것을 실행하면 Home Videos 대신 DirectoryName에 대해 Home만 표시됩니다. 아래에서 확인하세요.

 $ ./test1.ksh -n -b -d "Home Videos"
 Number of Args in Function1: 5
 Function1 Args: -n -b -d Home Videos

 Number of Args in SetArgs: 5
 SetArgs Args: -n -b -d Home Videos
 Var1 is set to:  No
 Var2 is set to:  Backup
 Directory Name: Home

내가 기대하고 있지만 실현하지 못한 것은 다음과 같습니다.

 $ ./test1.ksh -n -b -d "Home Videos"
 Number of Args in Function1: 4
 Function1 Args: -n -b -d "Home Videos"

 Number of Args in SetArgs: 4
 SetArgs Args: -n -b -d "Home Videos"
 Var1 is set to:  No
 Var2 is set to:  Backup
 Directory Name: Home Videos     <-- Without double quotes in the final usage.

제가 얻을 수 있는 도움은 크게 감사하겠습니다. 큰따옴표를 피하려고 시도했지만 성공하지 못했습니다.

이 문제를 해결하는 데 도움을 주신 시간과 노력에 감사드립니다.

감사합니다, 다니엘

답변1

사용하거나 $*인용 $@하지 않음절대말이된다.

"$*"는 위치 매개변수와 의 첫 번째 문자(또는 쉘에 따라 바이트)를 연결한 것입니다. $IFS"$@"위치 매개변수 목록입니다.

따옴표가 없으면 동일하지만 따옴표가 없는 다른 매개변수 확장과 마찬가지로 분할+glob(또는 빈 제거만 가능)이 적용됩니다 (일부 쉘은 비어 있어도 zsh인수를 분리합니다 ).$*$IFS

여기서 인수 목록을 전달하고 싶습니다.있는 그대로귀하의 기능에 따라 다음과 같습니다.

SetArgs "$@"
[...]
Function1 "$@"

ksh88에서 $IFS제대로 작동하려면 공백 문자(기본적으로 포함됨)를 포함해야 합니다(Bourne 쉘에서 상속된 버그, ksh93에서 수정됨).

또한 에뮬레이션 의 ksh이전 버전과 같은 일부 구현에서는zshksh

export DirectoryName=$1

분할+글로브 호출 사례입니다. export쉘 코드를 평가할 수 있는 Korn 유사 쉘의 명령 중 하나입니다.배열 인덱스의 산술 평가를 통해) 그렇군요.명령 주입 취약점이 발생하지 않도록 변수를 인용하는 것이 중요한 경우 중 하나입니다..

예:

$ (exec -a ksh zsh-4.0.1 -c 'export x=$a' ksh 'foo psvar[0`uname>&2`]')
Linux

이것은 [ $# -gt 0 ]의미가 없는 또 다른 분할+글로브 호출입니다(적어도 기본값인 에서는 문제가 될 가능성이 적습니다 $IFS).

답변2

getopts인수를 구문 분석하기 위해 내장 쉘 명령을 사용하는 것을 고려해 보셨나요 (예: @Stéphane Chazelas가 제안한 대로).이 댓글)? 그러면 이런 번거로움이 많이 줄어들 것입니다.

귀하의 경우 관련 코드는 다음과 같습니다.

while getopts "nbd:" argname
do
    case "$argname" in
    n)  Var1="No" ;;
    b)  Var2="Backup" ;;
    d)  DirectoryName ="$OPTARG" ;;
    ?)  echo -e "usage is..."
        exit 1 ;;
    esac
done

관련 정보