!["bash:[::予想整数式" [閉じる]](https://linux33.com/image/40306/%22bash%3A%5B%3A%3A%E4%BA%88%E6%83%B3%E6%95%B4%E6%95%B0%E5%BC%8F%22%20%5B%E9%96%89%E3%81%98%E3%82%8B%5D.png)
コマンドライン引数なしで、この関数はランダムな単語を返したいと思います。
#$-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+M
1つを追加します。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?$