Bashでコマンドライン引数を繰り返す

Bashでコマンドライン引数を繰り返す

誰かがこれら2つのコードブロックの違いを説明できますか?私はブロック#2がブロック#1と同じ出力を出力すると思いましたが、そうではありません。誰かが理由を説明できますか?

# ./arguments.sh hello my name is X

ブロック#1

for i
do
    echo $i
done

出力:

hello
my
name
is
X

ブロック#2

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

出力:

1
2
3
4
5

答え1

最初のブロックは(暗黙的に)コマンドライン引数を繰り返します。"$@"

for i in "$@"    # same as your "for i"
do
    echo "$i"
done

2番目のブロックは明示的に引数の数を繰り返し、インデックスを印刷します。

args=$#                          # number of command line args
for (( i=1; i<=$args; i+=1 ))    # loop from 1 to N (where N is number of args)
do
    echo $i
done

$#あなたの例に基づいて5と仮定すると、変数は、、、、、$i値を使用します。12345

他の(現在削除された)回答で指摘したように、次のようにインデックスごとにコマンドライン引数を参照できます。

args=$#
for (( i=1; i<=$args; i++ ))
do
    echo "$i - ${!i}"
done

答え2

エマ・ルーオの答え実際の質問に答えるには:

尋ねる:これら2つのコードブロックの違いは何ですか?なぜ別の出力を提供するのですか?

ㅏ:最初のループはコマンドラインパラメータを繰り返し、2番目のループはパラメータを繰り返します。数字(インデックス)。

...私の考えでは、この問題は6〜8分後に自分で見つけることができるようです。これは明らかです。 2番目のプログラムが次のようなことをしたいと思うかもしれません。

echo $$i                                        # This doesn't do what you want.

変数に格納されている数字で索引付けされ、 でi参照されるパラメーターを表示します$i。コメントで指摘したように、これは望むことを行いません。 (それする何かしてみてください。試してみてください。もちろん。 )しかし、これは実際に動作するものに近いです。

eval echo \$$i                                  # Don't do this.

または等しく、

eval echo '$'"$i"                               # Don't do this.

このコマンド

  • i(数値1、2、3、...のいずれか)の値を取得します。
  • $前に1つを付けて$1、背中を作ります$2$3
  • コマンドを使用して、eval次のように話します。 「作成したコマンドラインを使用して評価する私が入力したように。

これには実行効果があります。

echo $1
echo $2
echo $3

しかし、コメントからわかるように、これを避けるように努力する必要があります。  eval入力が一般的な単語ではない場合は危険です。サイトを検索してみてください。これについての説明がたくさんあります。

しかし、2番目のプログラムが最初のプログラムと同じことを行うようにするための非常に安全な方法があります。

echo $i

到着

echo ${!i}

さて、${i}まず$i!コマンドと同じ効果を提供しますeval。 (例:または)の値を${!x}見つけて使用します。x$x${x}それ検索する変数の名前です。したがって、x=foothen${!x}はと同じです$foo。上記のコードは同じことを行い、ivalueというパラメータを取得しますi

ところで、そうしない妥当な理由がなく、自分が何をしているのかを明確に知らない限り、シェル変数(たとえば、、および"$i")へのすべての参照を常に引用する必要があります。"$#""$args""${i}""${!i}"

関連情報