"bash:[::예상 정수 표현식" [닫음]

"bash:[::예상 정수 표현식" [닫음]

명령줄 인수 없이 이 함수가 임의의 단어를 반환하기를 원합니다.

#$ -ne 1에서도 작동하도록 linuxconfig.org의 임의 단어 생성기를 수정하고 있습니다.

function random-word {
    if [ $# -eq 0 ] ;
    then 
        echo "I only take one argument, dummy"
        # previously was exit 0
    fi

    # Constants 
    X=0
    ALL_NON_RANDOM_WORDS=/usr/share/dict/words

    # total number of non-random words available 
    non_random_words=`cat $ALL_NON_RANDOM_WORDS | wc -l` 

    # while loop to generate random words  
    # number of random generated words depends on supplied argument 
    while [ $X -lt "$1" ] 
    do 
    random_number=`od -N3 -An -i /dev/urandom | 
    awk -v f=0 -v r="$non_random_words" '{printf "%i\n", f + r * $1 / 16777216}'` 
    sed `echo $random_number`"q;d" $ALL_NON_RANDOM_WORDS 
      let "X = X + 1" 
    done

명령문이 실행되지만 bash 오류가 발생합니다.

$ bob
I only take one argument, dummy
bash: [: : integer expression expected

bash 오류가 표시되지 않도록 하려면 어떻게 해야 합니까?

답변1

while [ $X -lt "$1" ]1달러도 평가되지 않습니다.

이런 일이 발생하지 않도록 나머지 코드를 else 블록으로 이동하세요.

function random-word {
    # from linuxconfig.org 

    if [ $# -eq 0 ] 
    then 
        echo "I need an argument, dummy"
        # To be extra friendly, give them a random word.
        echo "Here's a random word:"
        random-word 1
    else
        # Constants 
        X=0

         ...

        sed `echo $random_number`"q;d" $ALL_NON_RANDOM_WORDS 
          let "X = X + 1" 
        done
    fi
}

답변2

블록이 필요하지 않습니다 else. 여러 인수를 받았다고 해서 실패할 필요는 없습니다. 실패하는 경우에만 실패하면 됩니다.아니요논쟁을 벌인 다음 다른 모든 것을 무시하거나 적어도 논쟁을 얻지 못하면 그만 둘 수 있습니다.

set -- "${1?ERR: Where\'s my argument?!?!}"

이 진술이 모든 것을 수행합니다. 이는 동일한 효과를 가지지만 첫 번째 매개변수가 nullstring인 경우에도 실패합니다 ''.

set -- "${1:?ERR: Where\'s my argument?!?!}"

물론 대화형 셸에서 셸 함수를 호출하는 것이 중요하다면 대화형 셸도 종료될 수 있으므로 다음과 같이 할 수 있습니다.

(: "${1:?Where\'s my argument?}") || return && set -- "$1"

...이 문제도 처리합니다. 그러나 제 생각에는 쉘 함수는 절대적으로 필요한 경우를 제외하고 대화형 쉘에 영향을 주어서는 안 됩니다. 예를 들어 현재 쉘 변수 등을 변경해야 하는 경우입니다. 따라서 위보다 더 나은 접근 방식은 함수를 다음과 같이 하위 쉘로 선언하는 것입니다.

fn() (set -- "${1:?Where\'s my argument?}" && echo "$1")

...하다.

또 다른 방법은 모든 매개변수를 승인하고 연결하는 것입니다. 따라서 모든 매개변수는 각 경우에 하나로 간주됩니다. 다음을 수행할 수 있습니다.

fn() (                              
    : "${1:?ERR: Where\'s my argument?}"
    set -- "$*" && echo "$1" 
)
fn '' ; fn here are a lot of arguments that will all be treated as one
###OUTPUT###
sh: line 2: 1: ERR: Where's my argument?
here are a lot of arguments that will all be treated as one

나는 개인적으로 일반적으로 일어나는 일을 좋아하지 않습니다 sh: line 2: 1:. 적어도 대화형 셸에서는 그렇습니다. 나는 일반적 으로 터미널의 줄 시작 부분으로 돌아가서 해당 비트를 재정의하지만 여전히 더 유용한 정보를 로그에 출력하도록 앞에 CTRL+V CTRL+M하나를 추가합니다 . ERR:좋다:

fn() (                              
    : "${1:?^MERR: Where\'s my argument?}"
    set -- "$*" && echo "$1" 
)
fn ; fn 2>&1 | cat -A
###OUTPUT###
ERR: Where's my argument?
sh: line 2: 1: ^MERR: Where's my argument?$

관련 정보