次の2つの最小シェルスクリプトを作成しました。
テスト1
#!/usr/bin/env bash
letterList=$1
for letter in $letterList
do
echo $letter
done
そして第二
テスト2
#!/usr/bin/env bash
letterList=$1
test1 $letterList
実行すると、目的の出力をtest1 'A B C'
取得しA
ます。B
C
ただし、実行すると発生するとtest2 'A B C'
予想されますが、test1 'A B C'
実際の出力はA
。
したがって、入れ子になった変数のリストが読み込まれない、つまり実行されているように見えますtest1 A
。
何が起こっているのか、どのようにして欲しい結果が得られますか?
PS:関連する場合は、OS Xを使用しています。
ベストアンサー1
コードにリスト変数がありません。あなたはロープを持っています。
test1
引用符なしで拡張を使用する呼び出しです$letterList
。これにより、シェルはその値をスペース、タブ、および改行(デフォルト)から複数の単語に分割し、各単語にファイル名ワイルドカードが含まれている場合はファイル名ワイルドカードになります。結果の単語はtest1
別の引数として渡されます。
では、test1
これらのパラメータの最初のものをに入れますletterList
。
$letterList
文字列をtest1
from as isに渡すには、test2
呼び出し時に拡張子を二重引用符で囲む必要があります。
test1 "$letterList"
しかし、あなたは頼る$letterList
ループの値の分割はシェルで行われますがtest1
(問題を引き起こすのと同じメカニズム)、コードが誤ってファイル名のグロービングを実行するのを防ぐことはできません(たとえば、スクリプトをテストして何を意味するのtest2 "A B C *"
かを確認)。
合格したい場合リスト単一の文字列ではなくtest2
文字列の代わりにリストを使用して呼び出します。
test2 A B C "Hello World" "* *"
次に、test2
パラメータを次に渡しますtest1
。
#!/bin/sh
test1 "$@"
ここでは、"$@"
位置引数(スクリプトのパラメータ)のリストが展開され、個々の引数が参照されます。これは、このようなパラメータがHello World
呼び出し時に複数のパラメータに分割されず、test1
文字列が* *
2つに分割されず、ファイル名の一致が発生しないことを意味します。
でtest1
パラメータを繰り返します。
#!/bin/sh
for arg in "$@"; do
printf '%s\n' "$arg"
done
または
#!/bin/sh
for arg do
printf '%s\n' "$arg"
done
...またはパラメータのみを印刷したい場合
#!/bin/sh
printf '%s\n' "$@"
/bin/sh
これには特定の項目がないため、全体的にシェルとして使用していますbash
。