Ubuntu에서 이 while-case가 작동하지 않는 이유는 무엇입니까?

Ubuntu에서 이 while-case가 작동하지 않는 이유는 무엇입니까?

BSD에서 전체 Linux로 전환 중입니다. 우분투 16.04의 스크립트

#!/bin/sh
while (( "$#" )); do
   case "$1" in
    -i | --ignore-case)
        [ $# -ne 2 ] && echo "2 arguments i needed" && exit 1
        case_option=-i
        ;;
    -*)
        echo "Error: Unknown option: $1" >&2
        exit 1
        ;;
     *) # No more options
        break
        ;;
   esac

   shift
done

# -o, if not, then ...
find $HOME ! -readable -prune -o \
    -type f -name "*.tex" -exec grep -l $case_option "$1" {} + | vim -R -

오류는 루프에 있습니다.

  • sh ./script masi예상한 것과 동일한 출력을 반환합니다.
  • 달리기 sh ./script -i masi. 출력: 빈 파일. 예상 출력: 결과 목록. 스타우트는 ./script: 2: ./script: 2: not found Vim: Reading from stdin....

가능한 오류

  • while (( "$#" ))
  • ...

어떤 이유로 이 옵션을 전혀 사용할 수 없습니다.

getopts로 이동하려는 동기 - terdon의 답변

지도 시간그리고 대답여기

case_option=""

while getopts "i:" opt; do
    case $opt in
        i | ignore_case) 
            [[ $# -ne 2 ] && echo "2 arguments i needed" && exit 1
            case_option=-i
            ;;
        -*)
            echo "Error: Unknown option: $1" >&2
            exit 1
            ;;
        *) # No more options 
           break
           ;;
    esac
done

find $HOME ! -readable -prune -o \
   -type f -name "*.tex" -exec grep -l $case_option "$1" {} + | vim -R -

어디

  • ./script masi또는 전화를 통해 ./script -i masi.

while사례를 반복하는 방법은 무엇입니까 ?

답변1

dashshor 대신 and 를 사용하여 실행하기 때문에 실패합니다 bash. Ubuntu에서는 최소한의 POSIX 호환 셸인 /bin/sh심볼릭 링크입니다 . /bin/dash가장 간단한 해결책은 스크립트를 실행하는 것인데 bash예상대로 작동하지 않습니다.

bash ./script masi

또한 Shebang 라인이 있다는 점에 유의하십시오.

#!/bin/sh

즉, 실행할 필요가 없고 sh ./script실행만 하면 됩니다 ./script. 대신 bash를 가리키도록 shebang 줄을 변경하십시오 sh.

#/bin/bash

sh( Ubuntu에서) 고집한다면 루프를 다음과 같이 변경 dash해야 합니다 .while

while [ "$#" -gt 0 ]; do

또는 다음을 살펴보고 싶을 수도 있습니다.getopts.

답변2

getopts옵션 매개변수를 처리하면 스크립트가 수행하는 작업이 아무런 영향을 미치지 않습니다.

다음은 작은 작업 프레임워크입니다.

case_option="" 

while getopts "i:" opt; do 
    case $opt in 
        'i') 
                I_ARG=$OPTARG 
                ;; 
        '?') 
                exit 1 
                ;;  
    esac 
done
shift $(($OPTIND - 1)) 
echo $@ 

답변3

다음은 옵션 처리에 대한 두 가지 예입니다. 먼저 내장 셸을 사용한 getopts다음 getoptfrom 을 사용합니다 util-linux.

getopts옵션은 지원되지 않으며 --long짧은 옵션만 지원됩니다.

getopt둘 다 지원됩니다. 사용하시려면 getopt패키지에 있는 버전을 사용하시면 됩니다 util-linux.원하지 않는다다른 버전의 getopt를 사용하면 손상되어 사용하기에 안전하지 않으며 작동하는 유일한 버전 util-linux입니다 .getopt

다행히도 Linux에서는 util-linux손상된 버전을 특별히 설치하지 않는 한 이 버전만 사용할 수 있습니다.

getopts이식성이 뛰어나고(대부분 또는 모든 Bourne-Shell 하위 항목에서 작동) 자동으로 더 많은 작업을 수행하지만(예: 설정이 덜 필요하고 해당 옵션에 매개 변수가 있는지 여부에 따라 모든 옵션을 실행 shift하거나 shift 2대상으로 지정할 필요가 없음) 성능은 떨어집니다. (긴 옵션은 지원하지 않습니다)

-i어쨌든 () 옵션을 처리하는 것 외에도 ( ) 옵션과 인수 ( ) 가 필요한 옵션 의 예도 --ignore-case추가했습니다 . 수행 방법을 보여주는 것 외에 다른 목적은 없습니다.-h--help-x--example

의 경우 getopts코드는 다음과 같습니다.

#! /bin/bash

usage() {
# a function that prints an optional error message and some help.
# and then exits with exit code 1
[ -n "$*" ] && printf "%s\n" "$*" > /dev/stderr

cat <<__EOF__
Usage:
      $0 [-h] [ -i ] [ -x example_data ]

-i    Ignore case
-x    The example option, requires an argument.
-h     This help message.

Detailed help message here
__EOF__

exit 1
}

case_option=''
case_example=''

while getopts "hix:" opt; do
    case "$opt" in
        h) usage ;;
        i) case_option='-i' ;;
        x) case_example="$OPTARG" ;;
        *) usage ;;
    esac
done
shift $((OPTIND-1))

find "$HOME" ! -readable -prune -o -type f -name "*.tex" \
    -exec grep -l ${case_option:+"$case_option"} "$1" {} + |
    vim -R -

에서 :getoptutil-linux

#! /bin/bash

usage() {
# a function that prints an optional error message and some help.
# and then exits with exit code 1
[ -n "$*" ] && printf "%s\n" "$*" > /dev/stderr

cat <<__EOF__
Usage:
      $0 [ -h ] [ -i ] [ -x example_data ]
      $0 [ --help ] [ --ignore-case ] [ --example example_data ]

-i, --ignore-case    Ignore case
-x, --example        The example option, requires an argument.
-h, --help           This help message

Detailed help message here
__EOF__

exit 1
}

case_option=''
case_example=''

# getopt is only safe if GETOPT_COMPATIBLE is not set.
unset GETOPT_COMPATIBLE

# POSIXLY_CORRECT disables getopt parameter shuffling, so nuke it.
# parameter shuffling moves all non-option args to the end, after
# all the option args.  e.g. args like "-x -y file1 file2 file3 -o optval"
# become "-x -y -o optval -- file1 file2 file3"
unset POSIXLY_CORRECT

OPTS_SHORT='hix:'
OPTS_LONG='help,ignore-case,example:'
# check options and shuffle them
TEMP=$(getopt -o "$OPTS_SHORT" --long "$OPTS_LONG" -n "$0" -- "$@")

if [ $? != 0 ] ; then usage ; fi

# assign the re-ordered options & args to this shell instance
eval set -- "$TEMP"

while true ; do
  case "$1" in
    -i|--ign*) case_option='-i' ; shift ;;
    -x|--exa*) case_example="$2" ; shift 2 ;;

    -h|--hel*) usage ;;

    --) shift ; break ;;
     *) usage ;;
  esac
done

find "$HOME" ! -readable -prune -o -type f -name "*.tex" \
    -exec grep -l ${case_option:+"$case_option"} "$1" {} + |
    vim -R -

관련 정보