ls *、ls **お​​よびls ***の結果


86

コマンドlsを使用すると、すべてのディレクトリが一覧表示されます。しかし、ls *コマンドは何をしますか?私はそれを使用しましたが、ディレクトリをリストしています。星の前にある星はls、ディレクトリを一覧表示できる深さを意味していますか?

回答:


155

ls引数として渡されるディレクトリのファイルとコンテンツをリストし、引数が指定されていない場合は、現在のディレクトリをリストします。また、その動作に影響する多くのオプションを渡すこともできます(詳細man lsについては参照)。

lsという引数が渡されている場合、現在のディレクトリで*呼び出されるファイルまたはディレクトリを探し、*他のディレクトリと同様にリストします。文字を他の方法とは異なる方法でls扱いません*

ただしls *シェルコマンドラインの場合、シェルは*対応するシェルのグロビングファイル名生成またはファイル名拡張とも呼ばれます)ルールに従って拡張します。

異なるシェルは異なるグロビング演算子をサポートしますが、それらのほとんどは最も単純なグロブ演算子に同意し*ます。*パターンは任意の数の文字を意味するため*、a globはそのパターンに一致する現在のディレクトリ内のファイルのリストに展開されます。ただし.、ファイル名の先頭のドット()文字を明示的に一致させる必要があるため、*実際には.(辞書順で)開始しないファイルおよびディレクトリのリストに展開されるという例外があります。

たとえば、カレントディレクトリと呼ばれるファイルが含まれている場合は....foo-lfoo 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以下(ので、任意のファイルやディレクトリを(隠しファイルを除く)。

bashksh93数年後(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を含めるにはzshD グロブ修飾子(のように**/*(D))隠しファイルとディレクトリを検討していますが、唯一の隠されたトラバースしたい場合します隠しファイルを展開することはできませんが、必要です((*|.*)/)#*または**/[^.]*(D))。

魚のシェルはまた、サポートしています**。の以前のバージョンと同様にbash、ディレクトリツリーを下るときにシンボリックリンクに従います。ただし、そのシェルでは**/*とは異なり**ます。複数のディレクトリにまたがることができる**拡張機能です*。でfish**/*.c一致しますa/b/c.cが、一致しませんがa.ca**.c一致しa.cab/c/d.cおよびzsh**/.*インスタンスを書く必要があり.* **/.*ます。そこでは、***と理解されている**が続く*ように同じ**

tcshまた、追加globstarV6.17.01(2010年5月)でのオプションを両方サポート**し、***ラàをzsh

そうでtcshbashかつksh93、(対応するオプションが有効になっている場合(globstar))やfish**現在の1以下のすべてのファイルとディレクトリを展開し、***同じである**ためfish横断シンボリックリンク、**のためにtcshglobstar、と同じ*bashksh93(それはだけれどもこれらのシェルの将来のバージョンがシンボリックリンクを横断することも不可能ではありません)。

上記で、どの拡張もオプションとして解釈されないことを確認する必要があることに気づいたでしょう。そのためには、次のようにします。

ls -- *

または:

ls ./*

いくつかのファイル名が特別に扱われるかもしれないlsので、2番目が好ましいいくつかのコマンドがあります(それは重要ではありません)--。これは-、ほとんどのテキストユーティリティ、cdおよびたとえば文字をpushd含むファイル名の場合です。すべての引数の前に付けると、特別な意味がなくなります(少なくとも上記の場合)。=awk./

また、ほとんどのシェルには、グロビング動作に影響する多くのオプション(ドットファイルを無視するかどうか、ソート順、一致しない場合の処理​​など)があることに注意して$FIGNOREください。ksh

また、すべてのシェルではなくcshtcshfishzshあれば、グロブパターンは任意のファイルと一致しない、パターンが混乱を引き起こし、おそらくバグ展開されていない引数として渡されます。たとえば、現在のディレクトリに非隠しファイルがない場合

ls *

実際にls2つの引数lsとで呼び出します*。また、ファイルがまったくないため、*どちらも呼び出されないため、次のようなls(シェルではない)からエラーメッセージが表示ls: cannot access *: No such file or directoryされます。これはls、実際にグロブを拡張していると人々に思わせることが知られています。

次のような場合、問題はさらに悪化します。

rm -- *.[ab]

何がある場合*.a*.b、ファイルが現在のディレクトリに、あなたはと呼ばれるファイルの削除を終了していないかもしれません*.[ab](誤ってをcshtcshzsh報告する不一致のエラーをして呼び出すことはありませんrm(とfishサポートしていません[...])ワイルドカード)。

リテラル合格したいです場合*にはls、あなたはそれを引用しなければならない*のように何らかの方法で文字をls \*ls '*'ls "*"。POSIXのようなシェルでは、set -o noglobまたはを使用してグロビングを完全に無効にできますset -f(後者は/ エミュレーション以外zshでは機能しません)。shksh


¹ (*/)#常にサポートされていましたが、最初..../はzsh-2.0(および場合****/によってはそれ以前)のように簡略化され、次に2.1 **/で2.2の最終形式になる前(1992年初期)


22
本当に素晴らしい答えです!
アンドレアコルベッリーニ

7
別の良い例はfind -name *です。特により複雑なパターンでは、現在のディレクトリに一致するものが1つしかない場合、アスタリスクをに渡していないことに気付かないことがよくありますfind
njsg

私は引き続き+1を与えます、ここでunix.stackexchange.comで Stephane Chazelasがアクティブになっているのを見て本当にうれしいです!ステファン、いつものように素晴らしい貢献を!
ディミトレラドゥロフ

1
魚で*.[ab]は、で終わるすべてを削除しようとし.[ab]ます。[魚では特別ではありません。
コンラッドボロスキー14

35

コマンドのlsデフォルトはls .次のとおりです。現在のディレクトリ内のすべてのエントリを一覧表示します

コマンドls *は「*シェルパターンの展開でlsを実行する」ことを意味します

*パターンはシェルによって処理され、で始まるものを除き、現在のディレクトリ内のすべてのエントリに展開されます.。1レベル深くなります。

ダブルまたはトリプル*パターンの解釈は、使用される実際のシェルによって異なります。

*0個以上の文字に一致するワイルドカードです。一部の最新のシェルは、**パターンを見るとサブディレクトリに再帰します。


17
その余分除いて* やる何かを追加、globstarを説明する他の回答を参照してください。また、lsはアスタリスクとは無関係であり、これらのアスタリスクがまったく渡されていないことを明確にする必要があります。実行echo ls *すると、書き込み時に何が実行されるかがわかりますls *
njsg

12

最初に入力するのでは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、ユーザーごとのディレクトリが。


1
「これはbash、シェルとして使用していることを前提としています」←およびグロブスターが有効になっていないこと。shopt -s globstarもう一度試してください
...-njsg

set -x分かりやすく説明する別の方法は、毎回実行される「実際の」コマンドの印刷を開始することです(でオフにしますset +x)。
シュ

10

globstarオプションを有効にしたbash 4.xを含む一部のシェルで**は、再帰的なglobを実行し、一致するディレクトリを降順にします。追加のアスタリスクは、この操作をさらに変更しません。


1
私も私の答えで述べたようにその反対を用心ksh93してzshbash一般的に不要である再帰でトラバースシンボリックリンクを行います。
ステファンシャゼル

それは今のbash 4.3で修正されました
ステファンChazelas

1

「深く掘り下げる」場合は、次のようにls -R(再帰)オプションを使用するか、findを使用します。

find . -ls

「find」はディレクトリツリーの最下部まで( 'ls -R'のように)飛び込み、ディレクトリのリスト(-type d)、ファイルのみ(-type f)、または他の特性(/ etc / passwdにユーザーがいない、特定の許可、その他多数)。「find」は、スクリプティングでもやや安全です(シェル間のグロビング規則の不一致、およびダッシュを含むファイルの特別なエスケープなどのため)。

シェルワイルドカードグロビングは、ドットファイルのアスタリスク「*」だけでは機能しません。ドットファイルのみをリストするには、次を使用します。

ls .??*


-1

余分な*は深さレベルを追加しません。しかし、試してみると

 ls */*/*

-現在のフォルダ内のフォルダ内のサブフォルダのサブフォルダのリストを取得します...


違う。シェルによっては、余分な*sが深さレベルを追加します。
-njsg

それで、どのシェルが追加の星に深さレベルを追加しますか?
VB9-UANIC

いくつか。bashglobstarオプション付きのGNU 、kornシェル、およびzsh を含みます。そしておそらく他の人も、私は推測します。unix.stackexchange.com/a/62665/14831
njsg

-1

私の主なグリップは、エコー** / *。extが一般的に...

5月かどうか:現在のディレクトリにある.extファイルをリストします。

5月または5月ではない:。*。extファイルを含める

一般に、glob式は '** /'であり、結果としてヌル文字列(サブディレクトリなし)になる可能性があります。これは、プログラム入力のグロブ式を変換する方法です。もちろん、使用例でこれを説明するコメントがあることを保証します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.