シェル・コマンドライン引数(ベース)

コマンドラインパラメータ

\プログラム名は$ 0とします。
\ $ 1 \ $ 9は、位置パラメータです。
\ $#がパラメータの数です。
\ $は、*を参照するために、全体としてすべてのパラメータ
文字列として各パラメータを返すために、\ $ @は、あなたはを反復するforループを使用することができます
\ $?直近に実行されたコマンドの終了ステータス。0は正常に実行さを示している
コマンドの\ $ _最後の引数を。この効果はある。ショートカットキーESC +を使用します

位置パラメータ

9つ以上の位置パラメータ、複数のパラメータが同じサポートです。\ $ {10}このような形態の参照を使用するだけ。
\ $ 1と\ $ {1}効果は同じです。
括弧がなければ、その後、$ 10 \ \ $ 1と0の文字とみなされます。

スペースでのパラメータ値
の各パラメータは、スペースで区切られています。パラメータの値にスペースを含めるには、引用符(利用可能な単一または二重引用符)でなければなりません。

パラメータはテキスト文字列として渡された場合、引用符は、データの一部ではありません。彼らは単に開始と終了位置データを示しています。

スクリプト名を取得します。

スクリプト名のために\ $ 0が、メソッドによって返さ異なる呼び出しの結果が異なっています。次のスクリプトは、簡易印刷\ $値0です。

$ cat filename.sh 
#!/bin/bash
echo $0
$ ./ filename.sh
-bash: ./: 是一个目录
$ cat filename.sh 
#!/bin/bash
echo $0
$ ./filename.sh
./filename.sh
$ bash filename.sh 
filename.sh
$ bash /root/filename.sh 
/root/filename.sh
$ 

ベース名コマンドを使用して
あなたが判断されるスクリプトの名前を使用したい場合は、あなたがフィルタリングするには、コマンドベース名パス情報を使用することができます。次のようにコマンドの効果は次のとおりです。

$ basename /var/log/messages 
messages
$ 

したがって、上記のスクリプトは、このような方法で修飾することができます。

$ cat filename.sh 
#!/bin/bash
echo $(basename $0)
$ ./filename.sh
filename.sh
$ bash filename.sh 
filename.sh
$ bash /root/filename.sh 
filename.sh
$ 

テストパラメータ

パラメータが存在していることを保証するために、スクリプト内のパラメータを使用して、または彼らがエラーをランタイムがあります。

$ cat add.sh 
#!/bin/bash
echo $1 + $2 = $[ $1 + $2 ]
$ ./add.sh 1 2
1 + 2 = 3
$ ./add.sh 1
./add.sh:行2: 1 +  : 语法错误: 期待操作数 (错误符号是 "+  ")
$ 

文字列ではなく、誤差を基準としてのみの場合。上院は、デフォルトパラメータが空で合格しませんでした。

$ cat hello.sh 
#!/bin/bash
echo Hello $1 $2.
$ ./hello.sh Tom Jerry
Hello Tom Jerry.
$ ./hello.sh Jerry
Hello Jerry .
$ ./hello.sh
Hello .
$ 

パラメータが存在するかどうかを決定することは、
非空の文字列、そして-Z反し、空気がシェルで使用-n真実であると決定しました。上記のテストされている、未定義のパラメータは、デフォルトでは空です。

$ cat hello.sh 
#!/bin/bash
if [ -n "$1" ]
then
    echo Hello $1.
else
    echo Hello Nobody.
fi
$ ./hello.sh Tom
Hello Tom.
$ ./hello.sh
Hello Nobody.
$ 

ここでは、引用符で囲むために$ 1 \判決だそうでない場合は、文字列とみなされます。もちろん、非空の文字列は、結果は常にtrueになります。

パラメータの数を決定する
上記の例は、スクリプトは、パラメータの数を実現することが0よりも大きいと判断することができます。

$ cat hello.sh 
#!/bin/bash
echo 参数数量: $#
if [ $# -gt 0 ]
then
    echo Hello $1.
else
    echo Hello Nobody.
fi
$ ./hello.sh
参数数量: 0
Hello Nobody.
$ ./hello.sh Tom
参数数量: 1
Hello Tom.
$ ./hello.sh Tom Jerry
参数数量: 2
Hello Tom.
$ 

\ $#が引用されていないので、ここで-gt、二つの数字(INT)の前後で比較しました。
この方法はまた、パラメータが存在するか否かによって決定することができます。どちらの方法でも、同様の効果が、異なる書籍が誰かの使用を見てきました。

ここでは、2つのパラメータを渡す必要があり、同加算の例です。

$ cat add.sh 
#!/bin/bash
if [ $# -eq 2 ]
then
    echo $1 + $2 = $[ $1 + $2 ]
else
    echo 需要参数: 2, 实际参数: $#.
fi
$ ./add.sh 1 2
1 + 2 = 3
$ ./add.sh 1 2 3
需要参数: 2, 实际参数: 3.
$ ./add.sh 1
需要参数: 2, 实际参数: 1.
$ 

あなたが等しくない表現したい場合、つまり、 if [ $# -ne 2 ]

最後のパラメータを取得します
使用\ $番号のヒントです。使用して、${$#}可変パラメータの最後の一つであるように思われます。
しかし、それは真実ではありません、中括弧は、感嘆符の内側に交換する必要があり、ここで、\ $でこれを行うことはできません。

$ cat hello.sh 
#!/bin/bash
if [ $# -gt 0 ]
then
    echo Hello ${!#}.
else
    echo Hello Nobody.
fi
$ ./hello.sh Tom Jerry
Hello Jerry.
$ 

ノーコマンドライン引数た場合は、スクリプトの名前です$ 0 \リターン、です。

問題上記感嘆符は、効果は、参照変数値の代わりに、変数自体です。ポインタの値に似ています。番号#は、より直感的に説明するために、変数の名前に置き換え:

$ cat parameter.sh 
#!/bin/bash
paramater=key
key=value
echo "${paramater}"
echo "${!paramater}"
echo "${key}"
$ ./parameter.sh 
key
value
value
$ 

感嘆符がなければ、それは変数の値に直接行くことです。感嘆符は、変数名に対応する変数の変数値に行くことです。

すべてのパラメータを取得します。

\ $ *と\ $ @をすべての文字列を表現しているが、横断時の違いがあるでしょう。

$ cat all.sh 
#!/bin/bash
echo '$* 的效果:'
count=1
for i in "$*"
do
    echo $count: $i
    count=$[ $count + 1 ]
done
echo '$@ 的效果:'
count=1
for i in "$@"
do
    echo $count: $i
    count=$[ $count + 1 ]
done
$ ./all.sh Oliver Barry Kara Sara Kane
$* 的效果:
1: Oliver Barry Kara Sara Kane
$@ 的效果:
1: Oliver
2: Barry
3: Kara
4: Sara
5: Kane
$ 

\値全体では$ *を、あなたがトラバースすることはできません。あなたは、\ $ @を使いたい各変数を横断します。ここでは二重引用符は非常に重要です。

引用符なし、そして、それはループを反復処理のために渡された(多変量解析は、より一語よりも後に)、そのような二つのパラメータの効果は同じですの\ $ *との\ $ @の内容です。そして、文字列は、同じ効果を引用し、直接渡すことはありません。
引用符を使用すると、コンテンツの引用符が全体です。それは$ *を\されている場合は、すべてこの中に全体としての単語ではなく、解体です。それが$ @を\されている場合は、スペースバーを押し、この全体は、複数の単語にそこに分割されます。
ここではデモンストレーション効果は次のとおりです。

$ cat all2.sh 
#!/bin/bash
echo '$* 不加引号的效果:'
count=1
for i in $*
do
    echo $count: $i
    count=$[ $count + 1 ]
done
echo '$@ 不加引号的效果:'
count=1
for i in $@
do
    echo $count: $i
    count=$[ $count + 1 ]
done
echo '直接遍历不加引号的字符的效果:'
count=1
for i in Oliver Barry Kara Sara Kane
do
    echo $count: $i
    count=$[ $count + 1 ]
done
echo '加引号遍历的效果:'
count=1
for i in "Oliver Barry Kara Sara Kane"
do
    echo $count: $i
    count=$[ $count + 1 ]
done
$ ./all2.sh Oliver Barry Kara Sara Kane
$* 不加引号的效果:
1: Oliver
2: Barry
3: Kara
4: Sara
5: Kane
$@ 不加引号的效果:
1: Oliver
2: Barry
3: Kara
4: Sara
5: Kane
直接遍历不加引号的字符的效果:
1: Oliver
2: Barry
3: Kara
4: Sara
5: Kane
加引号遍历的效果:
1: Oliver Barry Kara Sara Kane
$ 

強調:特殊パラメータ\ $ @を各パラメータの効果は別々の単語に拡張され、二重引用符で使用する必要があります。使用する場合は、ループを反復処理の結果を反映します。

モバイル可変シフト

シフトコマンドは、コマンドラインパラメータを操作するために使用することができます。デフォルトでは、左の各パラメータ1位。削除パラメータは破棄され、復元することはできません。
まず、簡単にコマンドライン引数を解析することができ、このコマンドを使用するには、このコマンドの使用を習得。

使用例

以下は簡単な例です:

$ cat pop.sh 
#!/bin/bash
count=1
while [ -n "$1" ]
# while [ $# -ne 0 ]
do
    echo "$count: $1"
    count=$[ $count + 1 ]
    shift
done
$ ./pop.sh Oliver Barry Kara Sara Kane
1: Oliver
2: Barry
3: Kara
4: Sara
5: Kane
$ 

あるかどうかを決定するためのパラメータを決定する2つの方法があり、効果は同じです。

複数の位置を移動します

パラメータなしシフトして実行、あなたはいくつかのことができるようになります移動したい場所を指定します。

$ cat pop.sh 
#!/bin/bash
count=1
# while [ -n "$1" ]
while [ $# -ne 0 ]
do
    if [ -n "$2" ]
    then
        echo "$count: $1, $2"
        shift 2
    else
        echo "$count: $1"
        shift
    fi
    count=$[ $count + 1 ]
done
$ ./pop.sh Oliver Barry Kara Sara Kane
1: Oliver, Barry
2: Kara, Sara
3: Kane
$ 

単純な修正スクリプト上、2つの出力パラメータとは、2つの位置を移動させます。

処理オプション

スクリプトを呼び出すときに、シェル・スクリプトは、複数のコマンドラインパラメータを必要とする場合、すべてのパラメータが順序を固定しなければなりません。
それともあなたはまた、パラメータの値を指定するオプションを使用することができます。

シフトの場合

値を持つオプションがあり、この場合も、値のないオプションがあります。

$ cat format.sh 
#!/bin/bash
prefix=""    # 前缀
base="test"  # 默认字符串
suffix=""    # 后缀
upper=off    # 是否大写
# 解析命令行参数
while [ -n "$1" ]
do
    case "$1" in
        -a) suffix="$2"
            shift ;;
        -b) prefix="$2"
            shift ;;
        -s) base="$2"
            shift ;;
        -u) upper=on ;;
         *) echo "$1 is not an option"
            exit 1 ;;  # 发现未知参数,直接退出
    esac
    shift
done
# 添加前缀和后缀
output="${prefix:+${prefix}_}${base}${suffix:+_${suffix}}"
# 判断是否要全大写输出
if [ $upper = on ]
then
    output=${output^^}
fi
# 输出结果
echo "$output"
$ ./format.sh -a after
test_after
$ ./format.sh -s hello -b befor
befor_hello
$ ./format.sh -s hello -u -a after -b befor
BEFOR_HELLO_AFTER
$ ./format.sh -s hello -u -a after -b befor -l
-l is not an option
$ 

case文はオプションに対処するためのオプションを見つけることができます。コマンドラインで必要なパラメータを提供する場合、それは一般的な処理部の場合で取り扱うことができます。そして、ここに報告して終了(出口1)上の任意のパラメータを、任意の間違った構文解析エラーを提供する必要はありません。

パラメータバージョンは解決することができ
、このバージョンの試合に出力フォーマットのすべてのパラメータを:

$ cat format.sh 
#!/bin/bash
prefix=""    # 前缀
base="test"  # 默认字符串
suffix=""    # 后缀
upper=off    # 是否大写
# 显示声明一下这是个数组变量,其实没有必要
declare -a names  # 需要格式化输出的所有原始字符串
# 解析命令行参数
while [ -n "$1" ]
do
    case "$1" in
        -a) suffix="$2"
            shift ;;
        -b) prefix="$2"
            shift ;;
        -s) base="$2"
            shift ;;
        -u) upper=on ;;
         *) names=("${names[@]}" "$1") ;;
    esac
    shift
done
names[0]=${names[0]:-$base}
for name in "${names[@]}"
do
    # 添加前缀和后缀
    output="${prefix:+${prefix}_}${name}${suffix:+_${suffix}}"
    # 判断是否要全大写输出
    if [ $upper = on ]
    then
        output=${output^^}
    fi
    # 输出结果
    echo "$output"
done
$ 
$ ./format.sh -a after -b befor -u value1 value2 value3
BEFOR_VALUE1_AFTER
BEFOR_VALUE2_AFTER
BEFOR_VALUE3_AFTER
$ ./format.sh -a after after1 -b befor befor1 -u value1 value2 value3
BEFOR_AFTER1_AFTER
BEFOR_BEFOR1_AFTER
BEFOR_VALUE1_AFTER
BEFOR_VALUE2_AFTER
BEFOR_VALUE3_AFTER
$ ./format.sh -a after after1 -b befor befor1 -u -v value1 value2 value3
BEFOR_AFTER1_AFTER
BEFOR_BEFOR1_AFTER
BEFOR_-V_AFTER
BEFOR_VALUE1_AFTER
BEFOR_VALUE2_AFTER
BEFOR_VALUE3_AFTER
$ 

最後の二つの結果を参照してください、コマンドラインパラメータは、問題がある提供するが、プログラムが見つかりません。
最後から二番目の項目は、供給された引数が正しいと考えられるが、オプションやパラメータを交互にすることができます。
最後の項目は、不正なオプションを提供していますが、特定できません。
この問題を解決するために、我々は別々のパラメータとオプションにより統制のとれたアプローチする必要があります。次のセクションの内容。

スペースを持つ配列の問題は
多くの方法がありますが、配列要素に追加し、これは実践の配列の再作成は、次のとおりです。

array_name=("${array_name[@]}" value1 ... valueN)

文字列にスペースが含まれている場合は、それが必要な引用符で、いくつかの要素を追加することができます。

そして、コマンドライン引数\ $ @と\ $ *と同様に、すべての配列要素は、2つの類似のシンボルを持っています。最も厳格な方法が使用することです"${names[@]}"@二重引用符を。
注意を払う必要があり、それ以外の場合は、元の配列要素が分離されている破壊するスペースを持つ要素があり、要素を追加し、時間の要素を削除します。
ここで使用される要素を追加します。

names=("${names[@]}" "$1")

だけでなく、要素の配列は、要素は引用符で追加する必要がありますされ、またはスペースがある場合は、複数の要素に応じて、アレイに追加されます。

要素をトラバース使用します。

for name in "${names[@]}"

ときにのみトラバーサルを補正するために正しく追加します。その後、時間を通過するだけでなく、正しいことを確認します。
の効果を確認します。

$ ./format.sh -a after -b befor -u value1 "value2 value3" value4
BEFOR_VALUE1_AFTER
BEFOR_VALUE2 VALUE3_AFTER
BEFOR_VALUE4_AFTER
$ 

パーフェクト。

分離パラメータとオプション

ここでの引数は、パラメータ定義したオプション、その他の追加のコマンドラインパラメータに加えて、ということです。2を分離するために-ジャグリングのパラメータとオプションは、あなたが特殊文字(二点鎖線)を使用する必要があります。二点鎖線は、オプションのリストの終わりを示し、破線の背後にある二重のブレークはパラメータです。限りケースで裁判官プラスライン上の文と、このロジックに基づいています。
上記のスクリプトは、いくつかの変更を行います。

$ cat format.sh 
#!/bin/bash
prefix=""    # 前缀
base="test"  # 默认字符串
suffix=""    # 后缀
upper=off    # 是否大写
# 显示声明一下这是个数组变量,其实没有必要
declare -a names  # 需要格式化输出的所有原始字符串
# 解析选项
while [ -n "$1" ]
do
    case "$1" in
        -a) suffix="$2"
            shift ;;
        -b) prefix="$2"
            shift ;;
        -s) base="$2"
            shift ;;
        -u) upper=on ;;
        --) shift
            break ;;
         *) echo "$1 is not an option"
            exit 1 ;;  # 发现未知参数,直接退出
    esac
    shift
done
# 解析参数
while [ -n "$1" ]
do
    names=("${names[@]}" "$1")
    shift
done
names[0]=${names[0]:-$base}
for name in "${names[@]}"
do
    # 添加前缀和后缀
    output="${prefix:+${prefix}_}${name}${suffix:+_${suffix}}"
    # 判断是否要全大写输出
    if [ $upper = on ]
    then
        output=${output^^}
    fi
    # 输出结果
    echo "$output"
done
$ 

その後、使用中に、あなたがアイテムを入力する必要があり、このバージョンで、入力パラメータ、その後、分離二点鎖線のために。スクリプトが二点鎖線に遭遇すると、オプションの処理を停止し、パラメータとして引数の残りの部分になります。

$ ./format.sh -a after -b befor -u value1 value2 value3
value1 is not an option
$ ./format.sh -a after -b befor -u -- value1 value2 value3
BEFOR_VALUE1_AFTER
BEFOR_VALUE2_AFTER
BEFOR_VALUE3_AFTER
$ ./format.sh -a after -b befor -v -u -- value1 value2 value3
-v is not an option
$ 

初めてのデュアル破線、そのエラーを使用しないでください。
第二は、ダブルダッシュで正しいパラメータとオプションを分離しました。
[オプション]セクションでサード外観未定義のオプションは、エラーを見つけることができます。

概要
このセクションの内容は、次のgetoptのコマンドのための基礎を敷設されます。パースのコマンドライン引数を完了するために、私たちを助けることができるのgetoptは、定期的なオプションと、二重破線のパラメータで区切られたパラメータのリストを返します。
また、ここでは、マージオプションをサポートしていません。

$ ls -al

これらの問題は、getoptので解決するだけでなく、長いオプションをサポートすることができます。

おすすめ

転載: blog.51cto.com/steed/2443313