Apa itu direktori ./ dan ../?

20

Pertanyaan sederhana, tapi saya tidak yakin ke mana harus mencari dan google tidak menanggapi titik dan garis miring.

Saya hanya mencoba menghitung # file & direktori di direktori saat ini (tidak termasuk subfolder / file) dan berusaha untuk membedakan ls -1 | wc -ldan ls | wc -lkarena mereka tampak identik. Sebuah situs yang saya lihat berkata "Ingatlah bahwa ini juga menghitung direktori ./ dan ../." mengenai satu dengan ls -1, dan saya tidak yakin apakah itu berarti termasuk direktori sebelumnya atau sesuatu (yang saya tidak mau), tetapi tampaknya tidak melakukan itu dari pengujian.

Bisakah seseorang mengkonfirmasi mana dari mereka yang paling memadai untuk menghitung # file & direktori di direktori saat ini saja (bukan sub) dan apa artinya dengan direktori ./ dan ../?

Adam
sumber
"Ingat bahwa ini juga menghitung direktori ./ dan ../" salah (kecuali itu salah ketik untuk "." Dan "..".
vonbrand

Jawaban:

15

Setiap direktori pada sistem Unix (dan mungkin juga setiap sistem lainnya) mengandung setidaknya dua entri direktori. Ini adalah .(direktori saat ini) dan ..(direktori induk). Dalam kasus direktori root, ini menunjuk ke tempat yang sama, tetapi dengan direktori lain, mereka berbeda. Anda bisa melihatnya sendiri menggunakan perintah stat, pwddan cd(di Linux):

$ 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
/
$

Perhatikan itu bindan sbinmasing - masing memiliki dua tautan ke sana. Satu adalah entri direktori di direktori root, dan yang lainnya adalah .entri di dalam direktori itu.

Menggunakan lsdengan pipa wc -ladalah trik sederhana untuk menghitung jumlah garis dalam output ls '. Asumsinya adalah bahwa setiap file atau direktori akan menempati tepat satu baris dalam output. GNU akan, ketika outputnya adalah non-terminal, melakukan ini secara otomatis; yang lain mungkin perlu -1opsi untuk mengaktifkan perilaku secara eksplisit. wc -lhanya menghitung dan menampilkan jumlah baris ( -l) pada inputnya.

Masalah dengan pendekatan itu adalah bahwa di Linux dan pada sistem file yang secara tradisional digunakan di Linux, nama file dan direktori (mereka benar-benar satu dan sama dalam hal ini) diperbolehkan mengandung karakter baris baru . Di hadapan mereka, salah satu metode berantakan - entri tersebut akan dihitung sebagai dua atau lebih entri ketika pada kenyataannya mereka adalah satu.

Selama Anda menggunakan GNU ls, tidak memiliki entri direktori dengan nama yang mengandung karakter baris baru, dan tidak memiliki alias aneh untuk ls(misalnya, ls -a), keduanya akan menampilkan jumlah file dan direktori dalam direktori saat ini (atau ditentukan). Bagi kebanyakan orang, ini cukup baik, tetapi tidak berlaku dalam kasus umum .

Jika Anda perlu menangani karakter yang tidak biasa (terutama baris baru) dalam nama entri direktori dengan benar, saya sarankan menggunakan -bopsi ls untuk menghindarinya. ls -1bAakan mencetak setiap nama entri direktori pada barisnya masing-masing, keluar dari karakter yang tidak biasa (sehingga setiap entri direktori akan terlihat sebagai satu), termasuk dotfiles dan -directories. Tack on wc -luntuk baris perintah lengkap ls -1bA | wc -lyang akan melaporkan jumlah file dan direktori di direktori saat ini (tetapi abaikan .dan ..; itulah perbedaan antara -adan -A), tetapi tidak turun ke subdirektori mana pun. Jika Anda tidak ingin ada dotfile yang dihitung terhadap total, cukup abaikan -Aparameternya ls.

sebuah CVn
sumber
Baik -adan -Atermasuk file tersembunyi juga yang saya sadari saya ingin hindari, jadi paling banyak saya akan melakukannya ls -b | wc -l, tetapi ini memberi saya jawaban yang tepat. Apakah baris yang saya salin dan tempel tentang perintah ini salah? Jika itu benar, bukankah seharusnya saya mendapatkan output 8 ketika ada 6 file atau folder dalam direktori?
Adam
@ Adam ya, itu mungkin akan melakukan trik ("ls -b | wc -l"); Anda juga dapat menggunakan "-1" (tanda hubung + nomor satu) yang memaksa daftar dalam satu kolom alih-alih semua pada satu baris, tetapi itu tetap terjadi ketika memipakan ke perintah lain. Jadi (imho) saya akan membiarkannya sebagai "ls -1b | wc -l"; dan untuk "menguji", jalankan "ls -1b" dan hitung jumlah baris, kemudian jalankan "ls -1b | wc -l" dan verifikasi hasilnya. (Begitulah cara men-debug / menguji pipa.)
michael
@Sathathrion, FAQ itu cukup menyesatkan. Konvensi sistem file Unix tidak "aneh"; di mana mereka biasa itu adalah sistem lain mengambilnya. Baiklah. Kemudian dikatakan bahwa "perintah file menggunakan angka ajaib untuk mengidentifikasi ...", yang salah: Ini menggunakan banyak heuristik juga. Tidak terlalu bisa diandalkan dalam buku saya.
vonbrand
@vonbrand: cukup adil, tautan dihapus. Saya hanya men-skimnya dan sepertinya baik-baik saja. Saya tahu saya menemukan satu yang baik tetapi sekarang tidak dapat mengingat di mana itu.
Sardathrion
1
Anda salah: . dan .. adalah artefak bersejarah dari UNIX pada tahun 1970-an dan merupakan hasil dari saat tidak ada mkdir()panggilan sistem. Tidak semua filesystem memilikinya dan bahkan tidak diperlukan atau diharuskan oleh POSIX.
schily
6

Untuk menjawab pertanyaan dalam subjek:

Ketika direktori B dibuat di Unix, itu ditambahkan sebagai entri baru ke direktori A lain (direktori induknya), dan di B, dua entri ditambahkan: satu disebut .sebagai tautan keras ke dirinya sendiri, dan satu disebut ..sebagai hard tautan ke A.

Itu adalah satu-satunya tautan keras ke direktori yang diizinkan (meskipun beberapa versi lebih tua dari beberapa UNICE juga mengizinkan tautan sewenang-wenang).

itu sebabnya dengan sebagian besar sistem file ( btrfsmenjadi pengecualian), jumlah linksdirektori adalah indikasi dari berapa banyak subdirektori yang dimilikinya (akuntansi untuk ..entri mereka ).

Saat Anda mengganti nama / memindahkan direktori, jika itu ke direktori yang sama (dengan nama yang berbeda), hanya entri nama Ayang diubah. B .dan ..tidak terpengaruh. Tapi jika Anda memindahkannya melakukan direktori yang berbeda, maka ..di Bakan berubah. Itu menjelaskan mengapa Anda dapat mengganti nama direktori di mana Anda tidak memiliki akses tulis (dengan asumsi Anda memiliki akses tulis ke direktori induk) hanya selama Anda tidak memindahkannya ke direktori lain (jika tidak, kebutuhan untuk mengubah ..entri mencegah Anda memindahkannya).

Berhati-hatilah: /a/b/../cmungkin tidak sama dengan /a/ckarena /a/bmungkin merupakan tautan simbolis ke beberapa direktori lain.

Pengecualian untuk itu adalah ketika path itu diberikan ke cdperintah untuk beberapa shell. Mereka cdmemperlakukan .. secara logis mengabaikan ..entri dalam direktori. Alasan mengapa Anda sering melihat cd -Pdalam skrip yang ditulis dengan benar, untuk menonaktifkan fitur yang dapat menyebabkan kebingungan dan inkonsistensi.

Untuk menghitung jumlah entri dalam direktori saat ini tidak termasuk .dan ..dengan bash, Anda dapat melakukan:

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

Dengan zsh:

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

Mudah dibawa:

find . ! -name . -prune -print | grep -c /
Stéphane Chazelas
sumber
Saya agak bingung; ketiga dari yang Anda daftarkan menambahkan satu ke hitungan yang sebenarnya. misalnya jika saya memiliki 6 file atau folder dalam direktori, mereka menghasilkan 7, bukan 6. Bagi saya, sepertinya ls | wc -lhanya ada satu yang mengecualikan .dan..
Adam
1
@ Adam, lstidak mencantumkan file tersembunyi. Anda harus ls -Amendapatkan yang sama seperti itu. JIKA Anda tidak ingin menghitung file yang disembunyikan, lepas dotglob(untuk bash) atau D(untuk zsh) atau tambahkan ! -name '.*'sebelum -printuntuk find.
Stéphane Chazelas
Ya, saya baru memperhatikan ini setelah benar-benar daftar file. Tahukah Anda mengapa ls | wc -lmasih memberi saya jawaban yang benar dan mengecualikan file tersembunyi, .& ..?
Adam
1
Adam, di direktori Anda, Anda punya ., ..dan file lain yang namanya dimulai dengan .yang tidak terdaftar oleh ls tetapi akan oleh ls -A. Jadi ls | wc -ltidak memberi Anda jawaban yang benar karena tidak menghitung file tersembunyi itu.
Stéphane Chazelas
1
Ya, .dan ..merupakan file tersembunyi sejak dimulai dengan a .. Bahkan ada legenda yang menjelaskan bahwa dotfiles disembunyikan secara tidak sengaja karena implementasi awal lsdimaksudkan hanya untuk mengecualikan .dan .., tetapi ada bug yang menyebabkannya mengecualikan file yang dimulai dengan .. ls | wc -ltidak berfungsi jika nama file mengandung karakter baris baru.
Stéphane Chazelas
1

Saya bukan ahli Linux yang hebat, tapi saya tahu Linux (dulu administrator 16 tahun yang lalu, di Slackware :) waktu yang lama

direktori ./ dan ../ sederhana:. adalah direktori saat ini, .. adalah direktori sebelumnya (di pohon pwd -local directory command-

Jika itu menghitungnya, saya rasa mereka menambahkan 2 ke total daftar, tidak benar-benar pergi secara rekursif dan menghitung direktori di bawah yang sekarang, dan juga menghitung lagi direktori saat ini (.) :))

Jadi pada dasarnya saya pikir itu menambah nilai 2 untuk sudah menghitung (file) dalam direktori saat ini.

Ada yang benar kalau aku salah.

Saya hanya memposting untuk membantu dan melihat bahwa tidak ada yang menjawab pertanyaan ini di sini, mereka mungkin sibuk. Tapi coba saja dan lihat apakah Anda memiliki 10 file dan dapatkan hitungan 12 maka itu saja.

Adrian Tanase
sumber
Ya, Adrian benar:. adalah dir saat ini dan .. adalah direktori tepat di atas dalam hierarki.
schaiba
.. tidak selalu merujuk ke direktori sebelumnya di pohon: di "/" .. merujuk ke direktori saat ini juga.
Bonsi Scott
karena Anda mungkin berada di / root dari sistem file?
Adrian Tanase
Jika itu menambahkan dua ke # file dalam direktori mengapa saya mendapatkan jawaban yang benar ketika mengujinya di terminal pada osx? misalnya direktori dengan 6 file atau folder akan menampilkan 6, bukan 8 ketika saya melakukannyals | wc -1
Adam
Saya menyadari bahwa itu karena mereka termasuk file tersembunyi (yaitu .ds_store), tetapi saya masih tidak melihat bagaimana ls | wc -lmemasukkan .dan ..ketika saya mendapatkan jawaban yang benar, sebagai lawan dari jawaban yang tepat + 2.
Adam