web-dev-qa-db-ja.com

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

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

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

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

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

しかし、-fromおよび-toの値を取得する方法がわかりません。方法についてのアイデアはありますか?

86
Kristoffer

Bashscriptに提供する引数は、変数$1および$2および$3に表示されます。番号は引数を参照します。 $0はコマンド自体です。

引数はスペースで区切られているので、コマンドで-from-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を囲む二重引用符は必ずしも必要ではありませんが、二重引用符で囲まないと一部の文字列が機能しないため、推奨されます。

104
gitaarik

オプション名として「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の動作に関する簡単なチュートリアルです。

62
Manny D

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

30
StianE

スクリプトは、さまざまなマシン、シェル、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日で、プログラマーである同僚の約半数が、ランチャーファイルを使用したり、「使用法」に従う、または表示されるヘルプを読むにはあまりにも優れていることを知りました何かが間違っていて、全体を混乱させ、引数を間違った順序でスクリプトを実行し、スクリプトが適切に機能しないと不平を言っていました。私は聖職者であるため、すべてのスクリプトをオーバーホールして、同僚の証拠となるようにします。上記のコードセグメントが最初でした。

19
user1628658

Bashでは、$1はスクリプトに渡される最初の引数であり、$2は2番目などです。

/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 b(2つの引数)が呼び出され、foo2.sh "a b"を使用すると、bar.sh "a b"(1つの引数)が呼び出されます。パラメータがbashでどのように渡され、拡張されるかを常に念頭に置いておくと、頭痛の種が大幅に軽減されます。

6
Jakub M.