次の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
。
答え2
./test2 'a b c'
実行すると、次のようになります。
$1=a b c
したがって、最後の行は次のようになります。
test1 a b c
実行すると、test1
次のようになります。
$1=a
$2=b
$3=c
つまり、指定されたパラメータはtest1
引用符で囲まれていないため、1つではなく3つのパラメータになります。
test1
単一のパラメータを渡すには、変数を二重引用符で囲みます。つまり、最後の行を次のようtest2
に置き換えます。
./test1 "$letterlist"
../
.
$PATH
答え3
実際の目標が何であるかは不明です。あなたが明確に言う唯一のことは、3つの別々の行とtest2 'A B C'
出力をしたいということですA
。B
C
そのような結果を提供できる他の解決策があります。通常、出力は次のように見えます。 ケルムの答え。
test2
同じままにしてください。test1
次のように変更します。#!/bin/sh for letter in $* do printf '%s\n' "$letter" done
そうすれば、自然に行動が変わります
test1
。今$1
。したがって、、、および(単に、および代わりに)がtest1 'A B C' 'D E F'
6つの別々のラインに出力されます。A
B
C
D
E
F
A
B
C
$*
スペースを含む文字列を別の単語に分割するため、通常は使用をお勧めしません。たとえば、2つの"lazy dog"
単語(パラメータ)になります。しかし、これはまさにあなたが望む行動のようです。
printf
echo
ファイル名の先頭より少し安全です。-
または含まれています\
。このサイトではすでにこれについて詳しく説明しています。もっと知りたい場合は、検索してみてください。