バッシュ、引数なしの警告、およびケースの決定


110

私はバッシュを学んでいます。

引数が指定されていない場合にメッセージを表示する簡単なスクリプトを実行したいと思います。そして、値に応じて引数として数値を与えると、それは何らかのことを行います。

また、bashの初心者向けの最良のオンラインマニュアルの提案を知りたいです。

ありがとう

回答:


176
if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 0
fi

case "$1" in
    1) echo 'you gave 1' ;;
    *) echo 'you gave something else' ;;
esac

高度なバッシュ・スクリプティングガイドはかなり良いです。その名前にもかかわらず、それは基本を扱います。


RE:「0を出る」。スクリプトを終了することが彼の意図したことだったかどうかはわかりません。しかし、はい、それは優れたガイドです。
Trampas Kirk 2010

メッセージがヘルプテキストであると想定して、「and」を「otherwise」と解釈しました。しかし、ワーナーはその行が何をしているか、そして彼がそれを望んでいるかどうかを理解できると確信しています:)
Thomas

もちろんありがとう!そして最後に、エラーメッセージをスクリプトでオフにして、シェルに表示されないようにするにはどうすればよいですか?
道を開く

あなたが呼んでいる特定のプログラムから出てくるエラーを意味しますか?標準出力および/または標準エラーストリームを忘却に送信するために、> /dev/nullおよび/または2> /dev/nullその後に置くことができます。
Thomas

4
欠落している引数が何か悪いことだと考える場合(スクリプトが正常に実行できないなど)、0以外の何かを返します(exit 1)。戻りコードと出口コードには、オンラインですぐに見つけられる別の規則がありますが、重要な点は、成功を示す0であってはならないということです。
Felix、

25

特定の引数が欠落している場合にのみベイル処理に関心がある場合は、パラメータ置換が最適です。

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

11

 if [ -z "$*" ]; then echo "No args"; fi

結果

No args

細部

-zは、stringの長さがゼロの単項演算子です。 $*すべての引数です。引用符は、安全のため、および存在する場合は複数の引数をカプセル化するためのものです。

このような他の演算子については、「単項」を使用man bashして検索(/キー)します。


7
これに関する(軽微な)問題は、引数を渡さないことと、空の文字列を引数として渡すことを区別しないことです。これは、状況によっては重要な場合があります。[$#-eq 0]を使用すると、両方のケースを適切に処理できます。
Idelic

1
ああ、(ba)shプログラミングの機微...これが私が嫌いな理由です。
Thomas

1
思う-zようmizzing
レイ・フォス

4

古いですが、以前の混乱のおかげで、今答えを書き直す理由があります。

if [[ $1 == "" ]] #Where "$1" is the positional argument you want to validate 

 then
 echo "something"
 exit 0

fi

位置引数$ 1がない場合、これは「Something」をエコーし​​ます。ただし、$ 1に特定の情報が含まれていることは検証されません。


$#明示的に引数の数の整数カウントです。これは「0」になり、引数がない場合でも「何か」をエコーするか、正の数になり、「何か」を正しくエコーします。ただし、使用する入力や入力の欠如に関係なく、チェック自体は何も実行しません。常に$#値を含むこと報告します。したがって、これは完全に間違っており、主張どおりに機能することはありません。
eschwartz

あなたはそれについて完全に肯定的ですか?この正確な形式を使用して意図したとおりに機能するスクリプトがいくつかあります。あなたの返事を読んで、私は試合とそれの欠如の両方について再テストしました。$#は、指定されていない場合や、シナリオの#と一致する位置引数がない場合、値を含みません。bashが存在しない位置引数の値を想定する理由は理解できません。
Ryan Smith

試してみてくださいecho $#、その後、スクリプト/tmp/test.shの内容として、あなたが利用できる持っているだけでなく、/ binに/ shの(または/ binに/ダッシュと何でも他のシェルの実装として/下/ binにbashのそれを実行します。/tmp/test.sh「0」をエコーしますれるようにコンソールが、/bin/dash /tmp/test.sh一方、/tmp/test.sh foo「1」をエコーし、/tmp/test.sh first second「2」エコーであろう。
eschwartz

によるとman bash、「特別なパラメーター」のセクションでは、「シェルはいくつかのパラメーターを特別に扱います。これらのパラメーターは参照されるだけであり、それらへの割り当ては許可されません。」および「#10進数の位置パラメーターの数に展開されます。」同様に、pubs.opengroup.org
onlinepubs /

コミュニケーションに問題があったようです。私は#をリテラル$#ではなく、特定の位置引数(つまり、2番目の引数を意味する場合は$ 2)のプレースホルダーとして意味しました。上記を確認した後、あなたは完全に正しいです、リテラル$#は常に引数の数に解決されます。混乱をお詫びします。
Ryan Smith
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.