GNU/Linux >> Belajar Linux >  >> Linux

Perbedaan Antara "du -sh *" Dan "du -sh ./*"?

Apa perbedaan antara du -sh * dan du -sh ./* ?

Catatan:Yang menarik bagi saya adalah * dan ./* bagian.

Jawaban yang Diterima:

$ touch ./-c $'an12tb' foo
$ du -hs *
0       a
12      b
0       foo
0       total

Seperti yang Anda lihat, -c file diambil sebagai opsi untuk du dan tidak dilaporkan (dan Anda melihat total baris karena du -c ). Juga, file bernama an12tb membuat kami berpikir bahwa ada file bernama a dan b .

$ du -hs -- *
0       a
12      b
0       -c
0       foo

Itu lebih baik. Setidaknya kali ini -c tidak diambil sebagai pilihan.

$ du -hs ./*
0       ./a
12      b
0       ./-c
0       ./foo

Itu lebih baik. ./ awalan mencegah -c dari diambil sebagai opsi dan tidak adanya ./ sebelum b di output menunjukkan bahwa tidak ada b file di sana, tetapi ada file dengan karakter baris baru (tetapi lihat di bawah untuk penyimpangan lebih lanjut tentang itu).

Ini adalah praktik yang baik untuk menggunakan ./ awalan jika memungkinkan, dan jika tidak, dan untuk data arbitrer, Anda harus selalu gunakan:

cmd -- "$var"

atau:

cmd -- $patterns

Jika cmd tidak mendukung -- untuk menandai akhir opsi, Anda harus melaporkannya sebagai bug kepada pembuatnya (kecuali jika itu karena pilihan dan didokumentasikan seperti untuk echo ).

Ada kasus di mana ./* memecahkan masalah yang -- tidak. Misalnya:

awk -f file.awk -- *

gagal jika ada file bernama a=b.txt di direktori saat ini (mengatur variabel awk a ke b.txt alih-alih menyuruhnya memproses file).

awk -f file.awk ./*

Tidak ada masalah karena ./a bukan nama variabel awk yang valid, jadi ./a=b.txt tidak diambil sebagai tugas variabel.

cat -- * | wc -l

gagal jika ada file bernama - di direktori saat ini, seperti yang memberitahu cat untuk membaca dari stdinnya (- khusus untuk sebagian besar utilitas pemrosesan teks dan untuk cd /pushd ).

cat ./* | wc -l

tidak apa-apa karena ./- tidak khusus untuk cat .

Hal-hal seperti:

grep -l -- foo *.txt | wc -l

untuk menghitung jumlah file yang berisi foo salah karena menganggap nama file tidak mengandung karakter baris baru (wc -l menghitung karakter baris baru, yang dihasilkan oleh grep untuk setiap file dan yang ada dalam nama file itu sendiri). Anda harus menggunakan sebagai gantinya:

grep -l foo ./*.txt | grep -c /

(menghitung jumlah / karakter lebih dapat diandalkan karena hanya ada satu per nama file).

Untuk grep rekursif , trik yang setara adalah dengan menggunakan:

grep -rl foo .//. | grep -c //

./* mungkin memiliki beberapa efek samping yang tidak diinginkan.

cat ./*

menambahkan dua karakter lagi per file, sehingga akan membuat Anda mencapai batas ukuran maksimum argumen+lingkungan lebih cepat. Dan terkadang Anda tidak menginginkan ./ itu untuk dilaporkan dalam output. Seperti:

grep foo ./*

Akan menghasilkan:

./a.txt: foobar

bukannya:

a.txt: foobar

Penyimpangan lebih lanjut

. Saya merasa harus mengembangkannya di sini, mengikuti diskusi di komentar.

$ du -hs ./*
0       ./a
12      b
0       ./-c
0       ./foo

Di atas, ./ . itu menandai awal setiap file berarti kita dapat dengan jelas mengidentifikasi di mana setiap nama file dimulai (di ./ ) dan di mana ia berakhir (di baris baru sebelum ./ next berikutnya atau akhir keluaran).

Terkait:Bagaimana cara menambahkan subdirektori bin dari direktori pertama di GOPATH ke PATH?

Artinya adalah output dari du ./* , bertentangan dengan du -- * ) dapat diuraikan dengan andal, meskipun tidak semudah itu dalam skrip.

Namun, ketika output masuk ke terminal, ada banyak cara lain yang dapat menipu Anda dengan nama file:

  • Karakter kontrol, urutan pelarian dapat memengaruhi cara sesuatu ditampilkan. Misalnya, r memindahkan kursor ke awal baris, b memindahkan kursor kembali, e[C maju (di sebagian besar terminal)…

  • banyak karakter yang tidak terlihat di terminal dimulai dengan yang paling jelas:karakter spasi.

  • Ada karakter Unicode yang terlihat sama seperti garis miring di sebagian besar font

     $ printf 'u002f u2044 u2215 u2571 u29F8n'
     / ⁄ ∕ ╱ ⧸
    

(lihat bagaimana hasilnya di browser Anda).

Contoh:

$ touch x 'x ' $'ybx' $'xn0t.u2215x' $'yr0t.e[Cx'
$ ln x y
$ du -hs ./*
0       ./x
0       ./x
0       ./x
0       .∕x
0       ./x
0       ./x

Banyak x tapi y hilang.

Beberapa alat seperti GNU ls akan mengganti karakter yang tidak dapat dicetak dengan tanda tanya (perhatikan bahwa (U+2215) dapat dicetak) ketika output masuk ke terminal. GNU du tidak.

Ada beberapa cara untuk membuat mereka menampakkan diri:

$ ls
x  x   x?0?.∕x  y  y?0?.?[Cx  y?x
$ LC_ALL=C ls
x  x?0?.???x  x   y  y?x  y?0?.?[Cx

Lihat caranya beralih ke ??? setelah kami memberi tahu ls bahwa set karakter kita adalah ASCII.

$ du -hs ./* | LC_ALL=C sed -n l0t./x$0t./x $0t./x$0t.342210225x$0t./thn0t.
Linux
  1. Perbedaan Antara Sumber ('.' Atau 'sumber') Dan Mengeksekusi File Di Bash?

  2. Perbedaan Antara [[ $a ==Z* ]] Dan [ $a ==Z* ]?

  3. Perbedaan Antara /opt Dan /usr/local?

  1. Perbedaan Antara .exrc Dan .vimrc?

  2. Perbedaan Antara '$ . Foo' Dan '$ ./foo'??

  3. Apa perbedaan antara fsync dan syncfs?

  1. Perbedaan antara /etc/crontab dan crontab -e

  2. Apa perbedaan antara ls dan l?

  3. Perbedaan antara file Perangkat dan driver perangkat