/bin/sh에서 Shift를 사용하는 방법은 무엇입니까? 변신: 그렇게 많이 변신할 수는 없다

/bin/sh에서 Shift를 사용하는 방법은 무엇입니까? 변신: 그렇게 많이 변신할 수는 없다

나는 스크립트에서 shiftshell( ) 문을 사용하는 방법을 이해합니다 . sh그러나 shift: can't shift that many 부분적으로 스크립트를 사용하는 것은 shift다음과 같습니다.

#!/bin/sh
.
.
.

test_sample(){
 while :; do
  case "${1-}" in 
  .
  .

  a)
   shift
     case "${1-}" in
     cmd1)
      echo "Test"
     cmd2)
      echo "Test 2"
     .
     .
     esac ;;

  b)
   shift
     case "${1-}" in
     cmd3)
      echo "Test 3"
     cmd4)
      echo "Test 4"
     .
     .
     esac ;;
   
  esac
  shift
done

return 0      
}

test_sample "$@"

스크립트는 명령줄 인수를 사용하여 명령줄에서 호출됩니다. 예상되는 동작은 ./test_sample.sh a cmd2"Test 2" 출력을 제공해야 합니다.

누구든지 이 오류를 해결하는 방법을 말해 줄 수 있나요?

미리 감사드립니다!

추신: 여기에 누락된 정보가 있으면 알려주시기 바랍니다.

답변1

문제는 종료되지 않는 루프가 있고 대신 shift변환할 인수가 더 이상 없을 때 사용하려고 한다는 것입니다.

수정된 코드:

#!/bin/sh

main () {
        while [ "$#" -ne 0 ]; do
                case $1 in
                        a)
                                case $2 in
                                        cmd1) echo 'Test 1' ;;
                                        cmd2) echo 'Test 2' ;;
                                        *) echo 'error a' >&2; exit 1
                                esac ;;
                        b)
                                case $2 in
                                        cmd3) echo 'Test 3' ;;
                                        cmd4) echo 'Test 4' ;;
                                        *) echo 'error b' >&2; exit 1
                                esac ;;

                        *) echo 'error' >&2; exit 1
                esac

                shift 2
        done
}

main "$@"

이제 외부 루프는 남은 매개변수가 있는지 테스트하고 그렇지 않은 경우 종료됩니다.

shift또한 루프 끝에서 두 매개변수 중 하나만 수행하고 그 이후 의 매개변수를 $1감지하는 데 a사용 합니다.b$2

다음 코드는 올바른 옵션으로 구문 분석하기 위해 위의 내용을 변경합니다 getopts. 그러면 a합계가 변경되므로 b이제 각각 옵션 인수가 있는 -asums 가 필요합니다.-b

$ ./script -a cmd1 -bcmd3
Test 1
Test 3
#!/bin/sh

main () {
        OPTIND=1

        while getopts a:b: opt; do
                case $opt in
                        a)
                                case $OPTARG in
                                        cmd1) echo 'Test 1' ;;
                                        cmd2) echo 'Test 2' ;;
                                        *) echo 'error a' >&2; exit 1
                                esac ;;
                        b)
                                case $OPTARG in
                                        cmd3) echo 'Test 3' ;;
                                        cmd4) echo 'Test 4' ;;
                                        *) echo 'error b' >&2; exit 1
                                esac ;;

                        *) echo 'error' >&2; exit 1
                esac
        done
}

main "$@"

관련 정보