コマンドls
を使用することを知っています すべてのディレクトリが一覧表示されます。しかし、 ls *
は何をしますか コマンドを実行しますか?私はそれを使用しました、そしてそれはただディレクトリをリストします。 ls
の前の星は ディレクトリを一覧表示する深さを意味しますか?
承認された回答:
ls
引数として渡されるディレクトリのファイルと内容を一覧表示します。引数が指定されていない場合は、現在のディレクトリを一覧表示します。また、動作に影響を与えるいくつかのオプションを渡すこともできます( man ls
を参照)。 詳細については)
ls
の場合 *
という引数が渡されています 、 *
というファイルまたはディレクトリを検索します 現在のディレクトリに、他のディレクトリと同じようにリストします。 ls
*
は扱いません 他の方法以外の方法でキャラクター。
ただし、 ls *
の場合 シェルです コマンドライン、つまりUnixシェルの言語のコード 、次にシェルはその *
を展開します そのグロビングによると (ファイル名の生成とも呼ばれます またはファイル名/パス名の拡張 )ルール。
異なるシェルは異なるグロビング演算子をサポートしますが、それらのほとんどは最も単純な *
に同意します 。 *コード> パターンは任意の数の文字を意味するため、
*
glob
として そのパターンに一致する現在のディレクトリ内のファイルのリストに展開されます。ただし、先頭のドット(。
)は例外です。 )ファイル名の文字は明示的に一致する必要があるため、 *
実際には、で始まらないファイルとディレクトリのリストに展開されます。
(辞書順)
たとえば、現在のディレクトリに。
というファイルが含まれている場合 、 ..
、 .foo
、 -l </ code> および
foobar
、 *コード> シェルによって2つの引数に展開され、
ls
に渡されます : -l </ code> および
foobar
、入力したかのようになります:
ls -l "foo bar"
または
'ls' "-l" foo bar
まったく同じコマンドを実行する3つの方法はどれですか。 3つのケースすべてで、 ls
コマンド(おそらく / bin / ls
から実行されます $ PATH
に記載されているディレクトリのルックアップから )には、「ls」、「-l」、「foobar」の3つの引数が渡されます。
ちなみに、この場合、 ls
最初の(厳密に言えば2番目の )オプションとして1つ。
さて、私が言ったように、異なるシェルは異なるグロビング演算子を持っています。数十年前、 zsh
** /
を導入しました 演算子¹は、(* /)#
の略で任意のレベルのサブディレクトリに一致することを意味します および***/
これは、ディレクトリを降順するときにシンボリックリンクをたどる以外は同じです。
数年前(2003年7月、 ksh93o +
)、 ksh93
その動作をコピーすることを決定しましたが、それをオプションにすることを決定し、 **
のみをカバーしました ケース( ***
ではありません )。また、 **
zsh
では単独では特別ではありませんでした ²( *
と同じ意味です **
以降、他の従来のシェルと同様 ksh93では、 **
で、任意の数の文字の後に任意の数の文字が続くことを意味します) ** / *
と同じ意味です (したがって、現在のものより下のファイルまたはディレクトリ(非表示ファイルを除く)³。
bash
コピーされたksh93
数年後(2009年2月、bash 4.0)、構文は同じですが、残念ながら違いがあります:bashの **
zsh
のようでした の***コード> 、つまり、サブディレクトリに再帰するときにシンボリックリンクをたどっていましたが、これは一般的にあなたが望んでいることではなく、厄介な副作用をもたらす可能性があります。シンボリックリンクが引き続き追跡されるという点でbash-4.3で部分的に修正されましたが、再帰はそこで停止しました。 5.0で完全に修正されました。
yash
**
を追加しました 2008年のバージョン2.0では、 extended-glob
で有効になっています オプション。その実装はzsh
に近いです その**
にあります 一人で特別ではありません。バージョン2.15(2009)では、 ***
が追加されました zsh
のように および独自の拡張機能の2つ:。**
および。***
再帰時に非表示のdirを含める( zsh
内) 、 D
グロブ修飾子 ( ** / *(D)
のように )は非表示のファイルとディレクトリを考慮しますが、非表示のディレクトリをトラバースするだけで非表示のファイルを展開したくない場合は、((* |。*)/)#*
が必要です。 または**/[^。]*(D)
。
魚の殻は**
もサポートしています 。以前のバージョンのbash
と同様 、ディレクトリツリーを下るときにシンボリックリンクをたどります。ただし、そのシェルでは ** / *
**
と同じではありません 。 **コード>
*
の拡張です 複数のディレクトリにまたがることができます。 fish
、 **/*。c
a / b / c.c
と一致します ただし、 a.c
ではありません 、a**。c
a.c
と一致します およびab/ c / d.c
およびzsh
の**/。*コード> たとえば、
。***/。*
と書く必要があります 。そこで、 ***
**
として理解されます 続いて*
**
と同じです 。
tcsh
globstar
も追加しました V6.17.01(2010年5月)のオプションであり、両方の **
をサポートします および***
àlazsh
。
したがって、 tcsh
、 bash
およびksh93
、(対応するオプションが有効になっている場合( globstar
))または fish
、 **コード> 現在のものの下にあるすべてのファイルとディレクトリを展開し、
***
**
と同じです fish
の場合 、 **
をトラバースするシンボリックリンク tcsh
の場合 globstar
を使用 、および *
と同じ bash
で およびksh93
(ただし、これらのシェルの将来のバージョンでもシンボリックリンクをトラバースすることは不可能ではありません)。
上記では、拡張がオプションとして解釈されないようにする必要があることに気付くでしょう。そのためには、次のようにします。
ls -- *
または:
ls ./*
いくつかのコマンドがあります( ls
には関係ありません )-
を使用する場合でも、2番目が望ましい場合 一部のファイル名は特別に扱われる場合があります。 -
の場合です ほとんどのテキストユーティリティでは、 cd
およびpushd
および=
を含むファイル名 awk
の文字 例えば。 ./
の前に すべての引数に対して、それらの特別な意味を削除します(少なくとも上記の場合)。
また、ほとんどのシェルには、グロビングの動作に影響を与えるいくつかのオプションがあることにも注意してください(ドットファイルを無視するかどうか、並べ替え順序、一致しない場合の対処方法など)。$FIGNOREも参照してください。
ksh
のパラメータ
また、 csh
以外のすべてのシェルで 、 tcsh
、 fish
およびzsh
、グロブパターンの場合 どのファイルとも一致しない場合、パターンは展開されていない引数として渡されるため、混乱が生じたり、バグが発生したりする可能性があります。たとえば、現在のディレクトリに隠しファイルがない場合
ls *
実際にls
を呼び出します 2つの引数ls
および*
。また、ファイルがまったくないため、 *
と呼ばれるものはありません。 どちらか、 lsからのエラーメッセージが表示されます (シェルではありません)like: ls:アクセスできません*:そのようなファイルまたはディレクトリはありません
、それは ls
であると人々に思わせることが知られています それは実際にグロブを拡大していました。
次のような場合、問題はさらに悪化します。
rm -- *.[ab]
*。a
がない場合 *。b
でもありません 現在のディレクトリにあるファイルの場合、*。[ab]
というファイルを削除してしまう可能性があります。 誤って( csh
、 tcsh
、および zsh
一致しないを報告します エラーが発生し、 rm
を呼び出さない (および fish
[...]
をサポートしていません ワイルドカード))。
リテラルの*
を渡したい場合 ls
へ 、その *
を引用する必要があります ls *
のような何らかの方法で文字 またはls'*'
またはls"*"
。 POSIXのようなシェルでは、 set -o noglob
を使用して、グロビングを完全に無効にすることができます。 またはset-f
(後者は zsh
では機能しません sh
でない限り / ksh
エミュレーション)。
。