옵션/매개변수/매개변수를 공백과 함께 스크립트에서 함수로 전달

옵션/매개변수/매개변수를 공백과 함께 스크립트에서 함수로 전달

안녕하세요 여러분, 미리 감사드립니다.

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

$:  ./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" 대신 "Home"의 DirectoryName만 가져옵니다. 아래를 참조하세요.

 $ ./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."$@"

따옴표가 없으면 동일하지만 따옴표가 없는 다른 인수 확장처럼 분할+글로브됩니다(또는 null로 제거됨 )(일부 쉘은 if가 null인 경우에도 zsh인수를 분할합니다 ).$*$IFS

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

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

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

또한 일부 구현의 경우 ksh(예: 이전 버전의 zsh에뮬레이션 ksh)

export DirectoryName=$1

Split+Glob 호출 상황입니다. export쉘 코드를 평가할 수 있는 Korn 쉘의 명령 중 하나입니다.배열 인덱스를 통한 산술 평가) 그렇군요.이러한 경우에는 명령 주입 취약점이 발생하지 않도록 변수를 인용하는 것이 중요합니다..

예:

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

이는 [ $# -gt 0 ]또 다른 분할+glob 호출이므로 의미가 없습니다(적어도 기본값에 문제가 있을 가능성은 없음 $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

관련 정보