./および../ディレクトリとは何ですか?


20

簡単な質問ですが、どこを見るべきかわかりません。グーグルはピリオドとスラッシュに反応しません。

私はちょうど(サブフォルダ/ファイルを含めない)、現在のディレクトリ内のファイル&ディレクトリの#をカウントしようとしていると差別化しようとしていたls -1 | wc -lls | wc -l、彼らは同じように見えるからです。私が見ていたサイトは、「これは./および../ディレクトリもカウントしていることを覚えておいてください」と言っていましたについてls -1は、前のディレクトリが含まれているのか、それとも何か(私は望まない)が含まれているのかどうかはわかりませんが、テストではそれが行われなかったようです。

誰かが、現在のディレクトリのみ(サブではない)のファイルとディレクトリの数をカウントするのに最も適切なものと、。/および../ディレクトリの意味を確認できますか?


「これは./および../ディレクトリもカウントしていることを覚えておいてください」は間違っています(「。」と「..」のタイプミスでない限り)
vonbrand

回答:


15

Unixシステム上のすべてのディレクトリ(およびおそらく他のすべてのシステムも)には、少なくとも2つのディレクトリエントリが含まれています。これらは.(現在のディレクトリ)と..(親ディレクトリ)です。ルートディレクトリの場合、これらは同じ場所を指しますが、他のディレクトリとは異なります。これはstat、Linux pwdおよびcdLinuxのコマンドを使用して確認できます。

$ cd /
$ stat . .. bin sbin | grep Inode
Device: 802h/2050d      Inode: 2           Links: 27
Device: 802h/2050d      Inode: 2           Links: 27
Device: 802h/2050d      Inode: 548865      Links: 2
Device: 802h/2050d      Inode: 2670593     Links: 2
$ pwd
/
$ cd ..
$ pwd
/
$

注意事項binsbinそれぞれが、それには2つのリンクがあります。1つはルートディレクトリのディレクトリエントリで、もう1つはそのディレクトリ.内のエントリです。

lsパイプへの使用は、wc -llsの出力の行数をカウントする簡単なトリックです。仮定は、各ファイルまたはディレクトリが出力で正確に1行を占めることです。GNU lsは、出力が非ターミナルの場合、これを自動的に行います。他のユーザーは-1、動作を明示的にオンにするオプションが必要になる場合があります。入力のwc -l行数(-l)をカウントして出力するだけです。

このアプローチの問題は、LinuxおよびLinuxで伝統的に使用されているファイルシステムでは、ファイル名とディレクトリ名(実際にはこの点ではまったく同じ)に改行文字を含めること許可されていることです。それらが存在する場合、どちらの方法もバラバラになります。実際にはそれらが1つである場合、それらのエントリは2つ以上のエントリとしてカウントされます。

GNU lsを使用している限り、改行文字を含む名前のディレクトリエントリがなく、ls(たとえばls -a)の奇妙なエイリアスはありません。両方とも、現在の(または指定された)ディレクトリ内のファイルとディレクトリの数を出力します。ほとんどの人にとってこれで十分ですが、一般的なケースでは有効ではありません。

ディレクトリエントリ名の異常な文字(主に改行)を適切に処理する必要がある場合は、lsの-bオプションを使用してそれらをエスケープすることをお勧めします。ls -1bAは、各ディレクトリエントリ名を独自の行に出力し、ドットファイルや-directoriesを含む、通常とは異なる文字をエスケープします(したがって、各ディレクトリエントリは1つとして表示されます)。上のタックwc -l完全なコマンドの行のためにls -1bA | wc -l、現在のディレクトリ内のファイルおよびディレクトリの数を報告しますた(ただし、無視.して..、違いだ-a-A)が、任意のサブディレクトリに降りません。合計にカウントされるドットファイルが必要ない場合は、への-Aパラメーターを単に省略しますls


両方-a-A隠しファイルも含めて、私は避けたいと気づいたので、せいぜいするだけですls -b | wc -lが、これは正しい答えを与えてくれます。このコマンドに関してコピーして貼り付けた行は間違っていますか?正しい場合、ディレクトリに6つのファイルまたはフォルダーがあるときに8の出力を取得する必要はありませんか?
アダム

@Adamはい、おそらくそれでうまくいくでしょう( "ls -b | wc -l"); また、「-1」(ダッシュ+ナンバー1)を使用することもできます。これは、すべてを1行で表示するのではなく、1列で強制的にリストしますが、それは別のコマンドにパイプするときに発生します。(imho)私はそれを "ls -1b | wc -l"のままにしておきます。「テスト」するには、「ls -1b」を実行して行数をカウントし、「ls -1b | wc -l」を実行して結果を確認します。(これがパイプのデバッグ/テストの方法です。)
マイケル

@Sardathrion、そのFAQは非常に誤解を招くものです。Unixファイルシステムの規則は「奇妙」ではありません。それらが一般的である場合、他のシステムがそれらをピックアップします。でも大丈夫。次に、「fileコマンドはマジック番号を使用して識別します...」と言いますが、これは間違っています。多くのヒューリスティックも使用します。私の本ではあまり信頼できません。
フォンブランド

@vonbrand:結構です、リンクは削除されました。私はそれをざっと見ただけで、それは問題ないように見えた。良いものを見つけたのは知っていますが、今はどこにあるのか思い出せません。
サルダスリオン

1
あなたは間違っています: 。および..は、1970年代のUNIXからの歴史的な遺物であり、mkdir()システムコールがまだなかった時代の結果です。すべてのファイルシステムがそれらを持っているわけではなく、POSIXによっても必要でも必要でもありません。
ずんぐり

6

件名の質問に答えるには:

UNIXでディレクトリBが作成されると、別のディレクトリA(その親ディレクトリ)に新しいエントリとして追加され、Bには2つのエントリが追加されます。1つは.それ自体へのハードリンク、もう1つ..はハードAへのリンク

これらは許可されたディレクトリへの唯一のハードリンクです(ただし、一部の古いバージョンの一部のUnicesでは任意のリンクも許可されていました)。

そのため、ほとんどのファイルシステム(btrfs顕著な例外)linksで、ディレクトリの数は、そのサブディレクトリの数(..エントリのカウント)を示しています。

ディレクトリの名前を変更/移動するときに、同じディレクトリ(別の名前)にある場合は、名前のエントリのみAが変更されます。B ...影響を受けません。あなたはそれが別のディレクトリを行う移動した場合でも、その後..にはB変更されます。これは、別のディレクトリに移動しない限り(親ディレクトリへの書き込みアクセス権があると仮定して)、書き込みアクセス権のないディレクトリの名前を変更できる理由を説明します(そうしないと、..エントリを変更する必要がなくなります)あなたはそれを移動することから)。

ただし、 他のディレクトリへのシンボリックリンクである可能性があるため/a/b/../c、同じではない可能性があります。/a/c/a/b

例外は、cd一部のシェルへのコマンドにそのパスが指定されている場合です。これらは、ディレクトリ内のエントリを論理的に無視してcd扱います。適切に記述されたスクリプトで頻繁に表示される理由は、混乱と矛盾を引き起こす可能性のある機能を無効にするためです。.. ..cd -P

.および..を除く現在のディレクトリのエントリ数をカウントするには、次のようにしますbash

shopt -s nullglob dotglob
set -- *
echo "$#"

zshの場合:

f=(*(ND))
echo $#f

移植性:

find . ! -name . -prune -print | grep -c /

私は少し混乱しています。リストした3つすべてが実際のカウントに1を追加します。私は、ディレクトリ内の6つのファイルやフォルダを持っている場合例えば、彼らは出力7、ない6.私に、それはのように思えるls | wc -l除く唯一のものである...
アダム・

1
@Adam、ls隠しファイルはリストしません。ls -Aそれらと同じものを取得する必要があります。隠しファイルを数えたくない場合は、dotglob(bashの場合)またはD(zshの場合)を外すか、の! -name '.*'-printにaを追加しfindます。
ステファンシャゼル

ええ、実際にファイルをリストした後、これに気付きました。なぜあなたは、知っていますかls | wc -l、まだ私のファイルに隠さ正解と除外を与え、...
アダム

1
Adam、あなたのディレクトリにはがあり...名前が.lsでリストされていないがでリストされている別のファイルがありますls -A。そのls | wc -lため、その隠しファイルはカウントされないため、正しい答えは得られません。
ステファンシャゼル

1
はい、.そして..彼らが開始するので、ファイルを隠されています.。早期実施は次のようにドットファイルが事故によって隠されていると説明している伝説でもありますlsのみ除外することを意味した.とは..、それが始まる任意のファイルを除外するためにバグがありました.ls | wc -lファイル名に改行文字が含まれる場合は機能しません。
ステファンシャゼル

1

私はLinuxの専門家ではありませんが、Linuxを知っています(16年前、Slackwareの管理者でした:)古き良き時代

./および../ディレクトリは簡単です。現在のディレクトリ、..は前のディレクトリ(pwd -local directory command-のツリー内)

それらをカウントする場合、リストの合計に2を追加し、実際に再帰的に行って現在のディレクトリの下のディレクトリをカウントせず、現在のディレクトリ(。)を再度カウントします:))

したがって、基本的には、現在のディレクトリ内の既にあるcount(files)に値2を追加すると思います。

私が間違っていれば誰でも私を修正します。

私は手伝うために投稿していますが、ここでこの質問に誰も答えていないのを見て、彼らは忙しいかもしれません。ただし、10個のファイルがあるかどうかを実験して確認し、12個のカウントを取得するだけです。


はい、エイドリアンは正しいです。は現在のディレクトリで、..は階層のすぐ上のディレクトリです。
シャイバ

..は、ツリー内の前のディレクトリを常に参照するわけではありません。「/」で..は現在のディレクトリも参照します。
ボンシスコット

あなたがファイルシステムの/ルートにいる可能性があるからですか?
エイドリアン棚瀬

ディレクトリ内のファイルの数に2を追加すると、osxのターミナルでテストするときに正しい答えが得られるのはなぜですか?たとえば、6個のファイルまたはフォルダーを含むディレクトリは、8個ではなく6個を出力しますls | wc -1
アダム

私は、彼らが(つまり.ds_store)隠しファイルを含めているので、それはだことに気づいたが、私はまだどのように表示されていないls | wc -lが含ま...私は正しい答えを得るとき正しい答え+ 2とは反対に、
アダム・
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.