"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")

...する。

別の方法は、すべてのパラメータを承認してリンクすることです。したがって、すべてのパラメータは各ケースで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+M1つを追加します。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?$

関連情報