シェルファイル名拡張子はリストの(*)エントリをどのように区別しますか?

シェルファイル名拡張子はリストの(*)エントリをどのように区別しますか?

私はまだシェル拡張を完全に理解していません(いつか理解できることを願っています)…
このコメントを見ました。スーパーユーザーの問題さて、まだ道沿いに駐車されているようです…

シェルなしでLinuxを使用することは、市内交通でフェラーリを時速50kmで運転するのと同じです。すべての喜びが消えるでしょう…

次の例がわかりません。 2番目の例「配列項目の数:」が最初の例と異なる階層またはその他の要因は何ですか?

シェルに「空間」が導入された場合はどうなりますか?それともecho空白を導入し、シェルは(おそらく)\ 0を使用しますか?

#!/bin/bash
# Make a couple of files whose names contain a space.
junkd=$HOME/junkd
mkdir $junkd # || exit 1
cd $junkd
touch f\ {1..2}
#
echo -n * |xxd         # This shows a space between the two names.
names=$(echo -n * )
echo -n "$names" |xxd  # This shows a space between the two names.
#
# So far, it seems that the shell is inserting a space between each filename.
#
array=( $names )
echo "array item count: ${#array[@]}" 
# 4 items... This shows that a space is the delimiter char ....
#
array=( * )
echo "array item count: ${#array[@]}" 
# 2 items... What happened to the shell introduced space?
#

ベストアンサー1

シェルコマンド(より正確には「簡単なコマンド」)は単語リストで構成されています。各単語は任意の文字列にすることができます。シェル語にはスペースと句読点を含めることができます。

を実行すると、echo -n *シェルはパス名拡張(ファイル名の生成またはワイルドカードとも呼ばれる)を実行し、*それを一致するファイル名のリストに置き換えます。したがって、拡張後、このコマンドは、echo4-nf 1の単語で構成されますf 2。このコマンドはecho2つの引数で実行され、引数の間にスペースを含む引数を出力します(-nオプションによって終了する改行文字はありません)。したがって、出力はf 1 f 2演習:2つの連続したスペースで構成される名前を持つ別のファイルを作成して実行したecho -n *後、出力を理解していることを確認してください。

これを実行すると、names=$(echo -n * )コマンドの出力がnames変数に保存されます。ここで行はと同じですnames='f 1 f 2'

今行きますarray=( $names )。これは配列割り当てですが、この場合の拡張には影響しません。引用符なしの変数拡張なので、$names単語を分割してパス名拡張を実行します。トークン化とは、変数の値(文字列)が空白の各シーケンスのさまざまな部分に分割されることを意味します(IFS正確なルールはシェル文書を検索してください)。 0個、1個以上の単語で終わることができます。ここで文字列は、および4つの単語fに分割され1ます。したがって、配列には4つの要素が含まれます(各要素は1文字の単語です)。f2演習:名前に2つの連続したスペースを含む追加ファイルの配列の正確な内容は何ですか?

次に、あなたはそれを試しましたarray=( * )。これには一般的な拡張が適用される配列の単語があり、最後の単語はパス名拡張です。一致するファイルが2つあるため、配列には各ファイルの名前であるというf 12つの単語が含まれますf 2

シェルプログラミングの実践に関するこの分析からどのようなアドバイスを得ることができますか?まず、一般的なシェルプログラミングの原則があります。特に理由がない限り、変数の拡張子の周りに二重引用符を付けてください。その後、リストを文字列変数に保存しないでください。ファイル名のリストを保存するには、配列に直接置きます。

files=(*)
ls -l "${files[@]}"

追加の練習:単一のアスタリスク(touch '*')で名前付きファイルを作成し、このコマンドを再実行します。出力を理解していますか?

また、zshは変数拡張のためにトークン化またはパス名拡張を実行しません。これはプログラミングをよりスマートにします。

おすすめ記事