如何在/bin/sh中使用shift?转变:不能转变那么多

如何在/bin/sh中使用shift?转变:不能转变那么多

我了解如何shift在 shell ( 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”。

谁能告诉我如何修复这个错误?

提前致谢!

PS:如果此处缺少任何信息,请告诉我。

答案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来检测aor b,然后$2检测之后的参数。

以下代码更改了上述内容以使用正确的选项解析getopts。这改变了你的a和 ,b所以我们现在期望-a-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 "$@"

相关内容