入れ子になったシェルスクリプトはリスト変数では機能しません。

入れ子になったシェルスクリプトはリスト変数では機能しません。

次の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ます。BC

ただし、実行すると発生するとtest2 'A B C'予想されますが、test1 'A B C'実際の出力はA

したがって、入れ子になった変数のリストが読み込まれない、つまり実行されているように見えますtest1 A

何が起こっているのか、どのようにして欲しい結果が得られますか?

PS:関連する場合は、OS Xを使用しています。

ベストアンサー1

コードにリスト変数がありません。あなたはロープを持っています。

test1引用符なしで拡張を使用する呼び出しです$letterList。これにより、シェルはその値をスペース、タブ、および改行(デフォルト)から複数の単語に分割し、各単語にファイル名ワイルドカードが含まれている場合はファイル名ワイルドカードになります。結果の単語はtest1別の引数として渡されます。

では、test1これらのパラメータの最初のものをに入れますletterList

$letterList文字列をtest1from 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

おすすめ記事