Bashのスクリプトパラメータ


103

次のように使用するシェルスクリプトを作成しようとしています。

ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

スクリプトは、画像ファイルをテキストファイルに変換します。これが私がこれまでに思いついたことです:

#!/bin/bash
export HOME=/home/kristoffer
/usr/local/bin/abbyyocr9 -rl Swedish -if ???fromvalue??? -of ???tovalue??? 2>&1

しかし、-fromとの-to値を取得する方法がわかりません。それを行う方法に関するアイデアはありますか?


回答:


124

あなたはbashscriptに提供引数は変数に表示されます$1し、$2及び$3数は、引数を指します。$0コマンド自体です。

引数はスペースで区切られているため、コマンドで-fromand -toを指定すると、これらの変数にも結果が含まれるため、次のようになります。

./ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

あなたは得るでしょう:

$0    # ocrscript.sh
$1    # -from
$2    # /home/kristoffer/test.png
$3    # -to
$4    # /home/kristoffer/test.txt

次のように、-fromとを省略する方が簡単-toな場合があります。

ocrscript.sh /home/kristoffer/test.png /home/kristoffer/test.txt

それからあなたは持っているでしょう:

$1    # /home/kristoffer/test.png
$2    # /home/kristoffer/test.txt

欠点は、正しい順序で指定する必要があることです。コマンドラインで名前付き引数を解析しやすくするライブラリがありますが、通常、単純なシェルスクリプトの場合は、問題がなければ簡単な方法を使用する必要があります。

その後、次のことができます。

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

$1とを囲む二重引用符$2は必ずしも必要ではありませんが、二重引用符で囲まないと一部の文字列が機能しないため、推奨されます。


69

オプション名として「from」と「to」を使用することに完全に慣れていない場合は、getoptsを使用してこれを実装するのはかなり簡単です。

while getopts f:t: opts; do
   case ${opts} in
      f) FROM_VAL=${OPTARG} ;;
      t) TO_VAL=${OPTARG} ;;
   esac
done

getopts コマンドライン引数を処理し、それらを便利に解析するプログラムです。

f:t:値(コロンで示される)を含む2つのパラメーターが必要であることを指定します。のようなものf:t:v-vフラグとしてのみ解釈されると言います。

opts現在のパラメータが格納される場所です。caseあなたがこれを処理する場所文です。

${OPTARG}パラメータに続く値を含みます。${FROM_VAL}たとえば/home/kristoffer/test.png、次のようなスクリプトを実行すると、値が取得されます。

ocrscript.sh -f /home/kristoffer/test.png -t /home/kristoffer/test.txt

他の人が示唆しているように、bashスクリプトを初めて作成する場合は、いくつかの基本事項をよく読んでください。これは、動作の簡単なチュートリアルgetoptsでした。


1
これは読みやすい解決策のようです。次に、2つのフラグをどのように指定しますか?
Zelphir Kaltstahl 2016年

@Zelphirでは、フラグの後の ":"を省略して、2つ以上のフラグを指定できます。たとえば、次のようにf:t:vsなります-f some_f -t some_t -v -s
h_s

34

変数"$1""$2"など"$3"を使用して引数にアクセスします。それらのすべてにアクセスするには、を使用する"$@"か、引数の数を取得します(引数$#が少なすぎたり多すぎたりしないか確認するのに役立つ場合があります)。


24

私のスクリプトがさまざまなマシン、シェル、さらにはcygwinバージョン間で完全に移植可能であることを確認する必要がありました。さらに、私がスクリプトを作成しなければならなかった私の同僚はプログラマーなので、これを使用することになりました。

for ((i=1;i<=$#;i++)); 
do

    if [ ${!i} = "-s" ] 
    then ((i++)) 
        var1=${!i};

    elif [ ${!i} = "-log" ];
    then ((i++)) 
        logFile=${!i};  

    elif [ ${!i} = "-x" ];
    then ((i++)) 
        var2=${!i};    

    elif [ ${!i} = "-p" ]; 
    then ((i++)) 
        var3=${!i};

    elif [ ${!i} = "-b" ];
    then ((i++)) 
        var4=${!i};

    elif [ ${!i} = "-l" ];
    then ((i++)) 
        var5=${!i}; 

    elif [ ${!i} = "-a" ];
    then ((i++)) 
        var6=${!i};
    fi

done;

理論的根拠:launcher.shスクリプトも含めました。これは、操作全体に互いに独立したいくつかのステップがあったためです(私は「準」と言っています。各スクリプトを単独で実行できたとしても、通常はすべて一緒に実行されたためです。 )、そして2日間で、プログラマーである私の同僚の約半数はすべて、ランチャーファイルを使用するには「良すぎる」、「使用法」に従う、または何かをするたびに表示されるヘルプを読むことができたことがわかりました間違っていて、全体をめちゃくちゃにしていて、引数を間違った順序でスクリプトを実行し、スクリプトが適切に機能しないと文句を言っていました。私はコレリックであるため、すべてのスクリプトをオーバーホールして、それらが同僚に耐性があることを確認することにしました。上記のコードセグメントは最初のものでした。


2
私はこれが好き。最後にセクションを追加しています `else echo"無効な引数:$ {!i} "((i ++))
fi`

6

bash $1では、スクリプトに渡される最初の引数、$22番目など

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

だからあなたは使うことができます:

./your_script.sh some_source_file.png destination_file.txt

二重引用符についての説明。

3つのスクリプトを検討してください。

# foo.sh
bash bar.sh $1

# cat foo2.sh
bash bar.sh "$1"

# bar.sh
echo "1-$1" "2-$2"

次に呼び出します:

$ bash foo.sh "a b"
1-a 2-b

$ bash foo2.sh "a b"
1-a b 2-

呼び出すとfoo.sh "a b"bar.sh a b2つの引数foo2.sh "a b"が呼び出され、同時にbar.sh "a b"1 つの引数が呼び出されます。パラメータがどのように渡され、bashで展開されるかを常に念頭に置いてください。これにより、頭痛の種を大幅に節約できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.