回答:
ls
引数として渡されるディレクトリのファイルとコンテンツをリストし、引数が指定されていない場合は、現在のディレクトリをリストします。また、その動作に影響する多くのオプションを渡すこともできます(詳細man ls
については参照)。
ls
という引数が渡されている場合、現在のディレクトリで*
呼び出されるファイルまたはディレクトリを探し、*
他のディレクトリと同様にリストします。文字を他の方法とは異なる方法でls
扱いません*
。
ただしls *
、シェルコマンドラインの場合、シェルは*
対応するシェルのグロビング(ファイル名生成またはファイル名拡張とも呼ばれます)ルールに従って拡張します。
異なるシェルは異なるグロビング演算子をサポートしますが、それらのほとんどは最も単純なグロブ演算子に同意し*
ます。*
パターンは任意の数の文字を意味するため*
、a glob
はそのパターンに一致する現在のディレクトリ内のファイルのリストに展開されます。ただし.
、ファイル名の先頭のドット()文字を明示的に一致させる必要があるため、*
実際には.
(辞書順で)開始しないファイルおよびディレクトリのリストに展開されるという例外があります。
たとえば、カレントディレクトリと呼ばれるファイルが含まれている場合は.
、..
、.foo
、-l
とfoo bar
、*
に渡すために、2つの引数にシェルによって展開されますls
。-l
そしてfoo bar
、あなたが入力したかのように、それは次のようになります。
ls -l "foo bar"
または
'ls' "-l" foo\ bar
まったく同じコマンドを実行する3つの方法です。3つすべてのケースで、ls
コマンド(おそらくに記載され/bin/ls
ているディレクトリのルックアップから実行される$PATH
)には、3つの引数「ls」、「-l」、「foo bar」が渡されます。
ちなみに、この場合、ls
最初(厳密に言うと2番目)をオプションとして扱います。
さて、私が言ったように、異なるシェルには異なるグロブ演算子があります。数十年前、zsh
導入**/
短いために、サブディレクトリの任意のレベルを一致させることを意味operator¹を(*/)#
して***/
ディレクトリを下降しながら、それがシンボリックリンクをたどることを除いて同じです。
数年前(2003年7月ksh93o+
)に、ksh93
その動作をコピーすることを決定しましたが、オプションにすることを決定し、**
ケースのみを対象としました(対象外***
)。また、一方で**
一人では特別なものではありませんでしたzsh
(ちょうど同じ意味*
ので、他の伝統的なシェルのように**
は、ksh93で、任意の数の文字に続く文字の任意の数を意味する)**
と同じ意味**/*
現在の1以下(ので、任意のファイルやディレクトリを(隠しファイルを除く)。
bash
ksh93
数年後(2009年2月、bash 4.0)、同じ構文でありながら不幸な違いでコピーされました:bash **
はzsh
'sのような***
ものでした。つまり、サブディレクトリに再帰するときにシンボリックリンクをたどりました。厄介な副作用を引き起こす可能性があります。bash-4.3では、シンボリックリンクが引き続き追跡されるという点で部分的に修正されましたが、再帰はそこで停止しました。5.0では完全に修正されました。
yash
**
2008年にバージョン2.0で追加され、extended-glob
オプションで有効になりました。その実装はに近いだけで、特別なzsh
もの**
ではありません。バージョン2.15(2009年)では、それは追加***
のようにzsh
、独自の拡張機能の2:.**
及び.***
(で再帰時に隠されたのdirsを含めるには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月)でのオプションを両方サポート**
し、***
ラàをzsh
。
そうでtcsh
、bash
かつksh93
、(対応するオプションが有効になっている場合(globstar
))やfish
、**
現在の1以下のすべてのファイルとディレクトリを展開し、***
同じである**
ためfish
横断シンボリックリンク、**
のためにtcsh
とglobstar
、と同じ*
でbash
とksh93
(それはだけれどもこれらのシェルの将来のバージョンがシンボリックリンクを横断することも不可能ではありません)。
上記で、どの拡張もオプションとして解釈されないことを確認する必要があることに気づいたでしょう。そのためには、次のようにします。
ls -- *
または:
ls ./*
いくつかのファイル名が特別に扱われるかもしれないls
ので、2番目が好ましいいくつかのコマンドがあります(それは重要ではありません)--
。これは-
、ほとんどのテキストユーティリティ、cd
およびたとえば文字をpushd
含むファイル名の場合です。すべての引数の前に付けると、特別な意味がなくなります(少なくとも上記の場合)。=
awk
./
また、ほとんどのシェルには、グロビング動作に影響する多くのオプション(ドットファイルを無視するかどうか、ソート順、一致しない場合の処理など)があることに注意して$FIGNORE
ください。ksh
また、すべてのシェルではなくcsh
、tcsh
、fish
とzsh
あれば、グロブパターンは任意のファイルと一致しない、パターンが混乱を引き起こし、おそらくバグ展開されていない引数として渡されます。たとえば、現在のディレクトリに非隠しファイルがない場合
ls *
実際にls
2つの引数ls
とで呼び出します*
。また、ファイルがまったくないため、*
どちらも呼び出されないため、次のようなls(シェルではない)からエラーメッセージが表示ls: cannot access *: No such file or directory
されます。これはls
、実際にグロブを拡張していると人々に思わせることが知られています。
次のような場合、問題はさらに悪化します。
rm -- *.[ab]
何がある場合*.a
や*.b
、ファイルが現在のディレクトリに、あなたはと呼ばれるファイルの削除を終了していないかもしれません*.[ab]
(誤ってをcsh
、tcsh
とzsh
報告する不一致のエラーをして呼び出すことはありませんrm
(とfish
サポートしていません[...]
)ワイルドカード)。
リテラル合格したいです場合*
にはls
、あなたはそれを引用しなければならない*
のように何らかの方法で文字をls \*
かls '*'
かls "*"
。POSIXのようなシェルでは、set -o noglob
またはを使用してグロビングを完全に無効にできますset -f
(後者は/ エミュレーション以外zsh
では機能しません)。sh
ksh
¹ (*/)#
常にサポートされていましたが、最初..../
はzsh-2.0(および場合****/
によってはそれ以前)のように簡略化され、次に2.1 **/
で2.2の最終形式になる前(1992年初期)
find -name *
です。特により複雑なパターンでは、現在のディレクトリに一致するものが1つしかない場合、アスタリスクをに渡していないことに気付かないことがよくありますfind
。
*.[ab]
は、で終わるすべてを削除しようとし.[ab]
ます。[
魚では特別ではありません。
コマンドのls
デフォルトはls .
次のとおりです。現在のディレクトリ内のすべてのエントリを一覧表示します。
コマンドls *
は「*
シェルパターンの展開でlsを実行する」ことを意味します
*
パターンはシェルによって処理され、で始まるものを除き、現在のディレクトリ内のすべてのエントリに展開されます.
。1レベル深くなります。
ダブルまたはトリプル*
パターンの解釈は、使用される実際のシェルによって異なります。
*
0個以上の文字に一致するワイルドカードです。一部の最新のシェルは、**
パターンを見るとサブディレクトリに再帰します。
*
やる何かを追加、globstarを説明する他の回答を参照してください。また、lsはアスタリスクとは無関係であり、これらのアスタリスクがまったく渡されていないことを明確にする必要があります。実行echo ls *
すると、書き込み時に何が実行されるかがわかりますls *
。
最初に入力するのではecho
なく、入力することでプロセス全体ls
をわかりやすく説明し、コマンドの展開先を確認できます。
$ echo *
Applications Downloads Documents tmp.html
したがって、この場合には、ls *
に展開しますls Applications Downloads Documents tmp.html
$ echo **
Applications Downloads Documents tmp.html
$ echo ***
Applications Downloads Documents tmp.html
変化なし。これはbash
、あなたがシェルとして使用していることを前提としています-ほとんどの人はそうであり、異なるシェルは異なる動作をします。ash
またはcsh
またはksh
またはを使用している場合zsh
、異なる動作を期待できます。それが異なるシェルを持つことのポイントです。
それでは、別の(まだbash
)を試してみましょう。それで、グロビング(*
)演算子ができることを理解できます。たとえば、名前の一部でフィルタリングできます。
$ echo D*
Downloads Documents
そして興味深いことに、末尾のスラッシュは暗黙的にディレクトリ名の一部です。したがって*/
、ディレクトリ(およびディレクトリへのシンボリックリンク)のみが生成されます。
$ echo */
Applications/ Downloads/ Documents/
そして、スラッシュを中央に置くことで、複数のレベルでいくつかのフィルタリングを行うことができます。
$ echo D*/*/
Documents/Work/ /Documents/unfinished/
以来Downloads
ディレクトリは任意のサブディレクトリが含まれていない、それが出力に終わることはありません。これは、必要なファイルを調べるだけの場合に非常に便利です。私は常にこのようなコマンドを使用します:
$ ls -l /home/*/public_html/wp-config.php
これは、wp-config.php
ユーザーのpublic_html
ディレクトリの基本レベルに存在するすべてのファイルが存在する場合、それらをリストします。または、より完全にするために:
$ find /home/*/public_html/ -name wp-config.php
これは、任意のでしょうwp-config.php
任意のユーザの中のファイルpublic_html
のディレクトリまたはそのサブディレクトリのいずれかを、それがより効率的に単なる動作しますfind /home/ -name wp-config.php
、それは何も調べてないのではなくpublic_html
、ユーザーごとのディレクトリが。
bash
、シェルとして使用していることを前提としています」←およびグロブスターが有効になっていないこと。shopt -s globstar
もう一度試してください
set -x
分かりやすく説明する別の方法は、毎回実行される「実際の」コマンドの印刷を開始することです(でオフにしますset +x
)。
globstar
オプションを有効にしたbash 4.xを含む一部のシェルで**
は、再帰的なglobを実行し、一致するディレクトリを降順にします。追加のアスタリスクは、この操作をさらに変更しません。
ksh93
してzsh
、bash
一般的に不要である再帰でトラバースシンボリックリンクを行います。
「深く掘り下げる」場合は、次のようにls -R(再帰)オプションを使用するか、findを使用します。
find . -ls
「find」はディレクトリツリーの最下部まで( 'ls -R'のように)飛び込み、ディレクトリのリスト(-type d)、ファイルのみ(-type f)、または他の特性(/ etc / passwdにユーザーがいない、特定の許可、その他多数)。「find」は、スクリプティングでもやや安全です(シェル間のグロビング規則の不一致、およびダッシュを含むファイルの特別なエスケープなどのため)。
シェルワイルドカードグロビングは、ドットファイルのアスタリスク「*」だけでは機能しません。ドットファイルのみをリストするには、次を使用します。
ls .??*