Apakah cd. sudah pakai?

102

Salah satu tutorial yang saya ikuti secara singkat menyatakan bahwa cd .tidak ada gunanya. Saat mencoba mereplikasi masalah yang ditunjukkan oleh OP dalam rekursi tautan Simbolik - apa yang membuatnya "diatur ulang"? , Saya juga mencoba cd ., yang menunjukkan efek yang sama yang dijelaskan OP ( $PWDvariabel tumbuh ), yang dapat diatasi cd -P.

Ini membuat saya bertanya-tanya, adakah kasus di mana seseorang sebenarnya ingin menggunakannya cd . ?

Sergiy Kolodyazhnyy
sumber
20
Saya memiliki .zshrc kustom yang menjalankan berbagai pemeriksaan pada direktori saat berpindah direktori, misalnya salah satu dari cek tersebut adalah untuk secara otomatis mengaktifkan / menonaktifkan virtualenv yang cocok ketika memindahkan direktori. Kadang-kadang, saya mungkin memulai shell baru atau apa pun, dan cek itu tidak berjalan, dan saya biasanya gunakan cd .untuk memicu cek itu karena pendek dan sederhana. Meskipun saya pikir Anda bermaksud pertanyaan itu untuk lingkungan vanila.
Lie Ryan
29
Selain efek (jelas) aktif $PWD, cd .juga perubahan $OLDPWDke direktori saat ini. Saya (saat ini) tidak tahu mengapa ini mungkin berguna, tetapi demi kelengkapan ...
Andreas Wiese
5
Saya tidak berpikir saya pernah membutuhkan cd ., meskipun melihat jawaban di bawah, saya mungkin di masa depan, tetapi saya kadang-kadang digunakan pushd .ketika saya ingin dapat popdkembali ke direktori ini nanti. misalnya ketika menjalankan skrip build yang berfungsi configure, cd output...dan make, dan ketika selesai, saya ingin kembali ke direktori asli. Alih-alih menyimpan salinan buildscript saya sendiri yang berbeda dari yang diharapkan orang lain, saya hanya menjalankannya pushd .; ./BuildScriptName.sh; popd, dan ini juga memberi saya kebebasan untuk tidak popdkadang - kadang, dan popdkemudian sebagai gantinya.
3D1T0R
5
Belum lagi tentu saja itu '.' dan '..' tidak diimplementasikan dalam perintah cd itu sendiri, jadi tidak ada yang menetapkan untuk membuat fitur tertentu, itu hanya kombinasi dari hal-hal yang tidak memiliki tujuan nyata.
David S
1
@ruakh Tidak, program eksternal seharusnya tidak memengaruhi lingkungan eksekusi shell. Sebagian besar untuk kepatuhan POSIX yang memerlukan beberapa utilitas ada di luar shell, dan mengevaluasi status keluar dari perintah eksternal. Anda dapat membaca tentang tujuan di /bin/cdsini unix.stackexchange.com/q/50058/85039
Sergiy Kolodyazhnyy

Jawaban:

158

Saya pikir ini terlalu memikirkan masalah. cd .mungkin bukan sesuatu yang orang akan jalankan secara manual dalam hal-hal yang biasa, tetapi pasti adalah sesuatu yang dapat muncul dalam eksekusi terprogram (pikirkan situasi apa pun yang Anda mungkin cdke direktori yang berisi file, yang jalurnya disediakan oleh pengguna ). Oleh karena itu, ia tidak harus memiliki penggunaan khusus: selama memenuhi semantik yang biasa cd <some-path>, itu berguna.

Olorin
sumber
12
Setuju, .harus diperlakukan sebagai jalur yang valid yang ditentukan oleh cdsintaks saja.
Sergiy Kolodyazhnyy
18
Anda dapat menambahkan contoh berikut: Loops like while IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d). Selama perjalanannya, find menghasilkan .sebagai path, sehingga perintah cd "$Dir"diperluas ke cd .. Jadi, dalam skrip, ini sangat berguna.
rexkogitans
5
Sebagai contoh, sebuah skrip benar-benar berjalan cd ${path_to_directory}, tetapi pada beberapa titik ternyata direktori tersebut adalah direktori saat ini, path_to_directory = .jadi Anda perlu cd .bekerja untuk berjaga-jaga.
Demis
4
Dengan kata lain, utilitasnya adalah membuat kode tambahan ( ifpemeriksaan dan elseklausa, segala jenis casing khusus) tidak diperlukan.
jpmc26
2
Jadi itu berguna dalam arti bahwa x + 0 atau x * 1 berguna - operasi spesifik tidak berguna per se, tetapi itu berarti bahwa Anda dapat menangani 0 dan 1 sama dengan nilai lainnya, tanpa harus memperlakukannya sebagai kasus khusus.
user32929
127

Jalur direktori bisa berubah sejak perintah terakhir dijalankan, dan tanpa cd .bash dan shell ksh93 akan bergantung pada direktori kerja logis yang dijelaskan dalam posting yang ditautkan dalam pertanyaan, jadi panggilan cd .yang membuat masalah shell getcwd()syscall akan memastikan Anda jalur saat ini masih valid.

Langkah-langkah mereproduksi di bash:

  1. Dalam masalah tab terminal mkdir ./dir_no_1; cd ./dir_no_1
  2. Dalam masalah tab terminal yang berbeda mv dir_no_1 dir_no_2
  3. Dalam masalah tab terminal pertama echo $PWDdan pwd. Perhatikan bahwa direktori telah diubah namanya secara eksternal; lingkungan shell belum diperbarui.
  4. Masalah cd .; pwd; echo $PWD. Perhatikan nilainya telah diperbarui.

ksh93, bagaimanapun, tidak memperbarui informasi lingkungan, jadi cd .di ksh93 sebenarnya tidak berguna. Di /bin/dashdalam Ubuntu dan sistem berbasis Debian lainnya, cd .pengembalian dash: 3: cd: can't cd to .kesalahan, namun cd -P .berfungsi (tidak seperti di ksh93).

Sergiy Kolodyazhnyy
sumber
22
Baik untuk diketahui: Saya akan menambahkannya ke daftar informasi tidak berguna saya. ^^)
jayooin
12
@jayooin Senang saya bisa berkontribusi dalam daftar;)
Sergiy Kolodyazhnyy
8
Saya pikir Anda bisa melakukan mv ../dir_no_1 ../dir_no_2dalam yang sama terminal / bash.
ctrl-alt-delor
3
@ ctrl-alt-delor Dikonfirmasi, bekerja :)
Sergiy Kolodyazhnyy
1
@ymbirtt Pada kebanyakan shell, pwdsebenarnya adalah built in, namun memohon /bin/pwdtidak berpengaruh pada lingkungan shell - utilitas eksternal pada umumnya tidak mempengaruhi lingkungan shell. Alasan mengapa /bin/cddan /bin/pwdada adalah untuk kesesuaian POSIX, antara lain. Ada diskusi yang bagus tentang cd eksternal yang beberapa di antaranya mungkin berlaku /bin/pwdjuga
Sergiy Kolodyazhnyy
55

Kasus penggunaan lain cd .adalah ketika direktori Anda saat ini telah dihapus dan kemudian dibuat lagi. Pertimbangkan untuk mencoba yang berikut -

  1. Buat direktori temp
  2. cd temp dan kemudian lakukan ls
  3. Buka terminal lain dan hapus lalu buat ulang direktori itu temp
  4. Kembali dari terminal pertama, coba lakukan ls. Ini akan menghasilkan kesalahan -ls: cannot open directory .: Stale file handle
  5. cd . dan kemudian melakukan ls bekerja dengan baik
Sahil Agarwal
sumber
3
Ini tidak selalu berhasil. Dalam tanda hubung, misalnya, Anda akan mendapatkan: cd: can't cd to .Sekarang setelah saya melihatnya, ini sudah disebutkan dalam jawaban Sergiy (bergerak, menghapus / menciptakan kembali - pada dasarnya sama: direktori tempat Anda berada tidak lagi seperti aslinya path)
Olorin
12
Saya menggunakan ini banyak menguji penyebaran jarak jauh. Direktori tempat saya berada akan dihapus kemudian dibuat ulang oleh beberapa otomatisasi dan saya harus mengeluarkan cd .untuk pindah ke direktori baru dengan nama yang sama.
HP Williams
2
Saya menggunakan cd .semua waktu ketika saya memiliki shell yang direktori kerjanya saat ini dipasang dengan sshfs tetapi sesi ssh telah ditutup dan dibuka kembali.
jamesdlin
4
Dalam kasus seperti itu saya melakukan "cd $ PWD". Varian lain mungkin berfungsi, tetapi yang ini dengan jelas menyatakan maksudnya: mengekstrak apa yang seharusnya menjadi jalur saya saat ini (yaitu membaca konten dari PWDvariabel lingkungan), kemudian berjalan hierarki sistem file dari root, ke direktori yang kebetulan dapat dijangkau melalui jalur itu, apakah itu sebenarnya direktori yang sama atau tidak. Ini sangat cocok dengan use case dalam jawaban ini.
Stéphane Gourichon
3
Saya benar-benar terkejut, bahkan kaget, yang cd .bekerja ketika direktori telah dihapus tautannya dan direktori baru yang berbeda dibuat pada jalur sistem file yang sama. Direktori kerja saat ini telah dihapus tautannya dan mungkin sebagai bagian dari itu, direktori itu tidak lagi memiliki .atau ..entri, dan bahkan jika itu terjadi, .entri tersebut harus terus mengarah ke dirinya sendiri. Sepertinya shell atau kernel sedang mengeksekusi perintah cd berdasarkan pada apa nama path direktori bukan hanya mengakses .entri. Adakah yang bisa mengkonfirmasi perilaku itu?
Adrian Pronk
36

Anda dapat menghapus $OLDPWDdengan cepat cd ., jika harus ada kasus di mana Anda tidak ingin menunjuk ke mana saja "menarik". Itu juga akan mempengaruhi cd -.

unperson325680
sumber
16

Secara pemrograman, ini berguna sebagai no-op. Pertimbangkan jalur yang disediakan dari input eksternal.

read -p "Path to file: " p
dirn=$(dirname "$p")
file=$(basename "$p")
echo "dirn=$dirn, file=$file"
cd "$dirn"
ls -ld "$file"

Dengan path seperti "fred.txt" direktori akan menjadi ., mengarah kecd .

roaima
sumber
1
Ini berguna bahwa itu tidak menimbulkan kesalahan jika Anda sudah berada di direktori yang Anda navigasikan, tetapi saya tidak akan mengatakan bahwa itu berguna sebagai no-op.
Kapten Man
2
@CaptainMan tidak melakukan kesalahan jika Anda sudah berada di direktori (secara efektif) adalah no-op. The dirnameperintah menghasilkan .mana diperlukan untuk menghindari melanggar kode yang mengharapkan untuk dapat membagi jalan.
roaima
15

Ini biasa terjadi jika Anda harus bekerja dengan kabel USB yang buruk. Setelah perangkat terputus dan terhubung lagi, dan diautomatisasi ke direktori yang sama, Anda harus menggunakannya cd .untuk membuatnya berfungsi kembali.

pengguna23013
sumber
1
Tidakkah itu tergantung pada perangkat apa, bagaimana itu diakses, sistem file, OS, & c?
gidds
OS, mungkin. Tidak mungkin filesystem itu relevan, asalkan kernel dapat menemukan jalannya unmount saat sedang digunakan. Bagaimanapun, perintah itu digunakan dalam situasi yang tepat.
user23013
11

Perhatikan bahwa "." adalah cara yang tepat untuk menentukan nama file yang terbuka sebagai direktori kerja saat ini dari proses apa pun (termasuk proses shell tentu saja), dan "." selalu merupakan nama file yang valid di setiap dan semua direktori, termasuk direktori kerja saat ini. Nama tersebut .mungkin bukan nama yang valid untuk file untuk contoh proses tertentu jika, katakanlah, direktori kerja saat ini yang mendasarinya telah dihapus (atau menjadi "buruk", misalnya gagang NFS basi), tetapi itu adalah nama yang valid file yang dijamin ada di setiap direktori yang valid.

Jadi . harus argumen yang valid untuk perintah apa pun yang menerima nama direktori, dan dengan demikian dalam shell standar cd .harus menjadi perintah yang valid.

Apakah cd .bermanfaat atau tidak tergantung pada implementasi shell. Seperti disebutkan itu dapat berguna jika shell me-reset ide internal tentang pathname lengkap dari direktori yang aktif saat ini setelah memanggil chdirpanggilan sistem yang mendasarinya , katakan misalnya jika direktori yang mendasarinya (atau beberapa induknya) telah berganti nama.

Setidaknya beberapa shell yang saya tahu ( /bin/shpada FreeBSD dan NetBSD) akan dikonversi cd ""menjadi cd ., yang bisa dibilang merupakan fitur untuk mendukung penggunaan program dalam skrip shell di mana variabel dapat digunakan sebagai parameter (yaitu mengubah substitusi variabel kosong menjadi " melakukan apa-apa "hasil), meskipun sejarah komit FreeBSD mengatakan perubahan itu secara langsung karena menambahkan dukungan POSIX untuk mencegah kegagalan chdir(""), yang mandat POSIX harus gagal.

Beberapa shell lain akan menggantikan .dengan apa pun yang mereka simpan sebagai pathname yang sepenuhnya memenuhi syarat untuk direktori kerja mereka saat ini, dan dengan demikian bagi mereka ini memungkinkan untuk perilaku yang disebutkan dalam jawaban Sahil Agarwal .

Greg A. Woods
sumber
4

Saya menggunakan perintah ini hanya hari ini ketika saya mengubah cabang yang saya kerjakan di Git, dari dalam direktori yang pertama kali dibuat pada cabang yang sama. Rebase berjalan baik tetapi setelah itu, git statusmelakukan kesalahan. Setelah cd .semuanya normal.

(Saya bekerja di MobaXterm di Windows, kebetulan. Kalau-kalau Anda mencoba mereproduksi ini. Mungkin tidak terjadi pada sistem lain.)


Saya juga telah menggunakan perintah ini dalam direktori yang di-refresh oleh proses otomatis yang mengesampingkan direktori lama dan menggantinya dengan yang baru (sehingga sedekat mungkin dengan atomik). Bukan situasi yang umum tetapi cd .justru apa yang dibutuhkan.


Setelah membaca jawaban yang luar biasa ini dari Stephane Chazelas:

Saya sekarang mengerti bahwa kasus penggunaan saya di atas hanya berfungsi karena saya menggunakan bash, yang cd .setara dengan cd "$PWD". Saya sangat merekomendasikan membaca jawaban yang ditautkan.

Wildcard
sumber
1

Saya menggunakan cd .untuk menjalankan kembali hal-hal yang saya kelebihan cddengan melalui bashfungsi.

Dari saya ~/.bashrc:

# from the "xttitle(1)" man page - put info in window title
update_title()
{
    [[ $TERM = xterm ]] || [[ $TERM = xterm-color ]]  && xttitle "[$$] ${USER}@${HOSTNAME}:$PWD"
}

cd()
{
    [[ -z "$*" ]] && builtin cd $HOME
    [[ -n "$*" ]] && builtin cd "$*"
    update_title
}
waltinator
sumber
0

EDIT: Ini sudah disarankan oleh Sahil sebelumnya.

Ini berguna jika Anda berada di dalam folder yang dihapus dan diciptakan kembali oleh proses lain. Misalnya, dengan asumsi dua sesi terminal $1dan $2:

$1 mkdir d
$1 cd d
$1 touch f

$2 rm -rf /path/to/d # delete the folder where $1 is in ...
$2 mkdir /path/to/d # ... and recreate it

$1 touch g # cannot create file g because current dir doesn't exist anymore
touch: cannot touch ‘g’: Stale file handle
$1 cd . # go to the newly created dir (same path)
$1 touch g # works fine now

Saya tidak yakin di mana tepatnya (OS, SHELL, ...?) Akar penyebab perilaku ini.

Rolf
sumber
Ini sudah disebutkan oleh jawaban lain.
Kusalananda
-8

Tidak, itu tidak masuk akal. Baik dalam scripting, itu tidak melakukan apa-apa.

Federico
sumber
2
Bergantung pada shell, itu akan mengatur ulang $PWD, dan itu mungkin akan memanggil fungsi shell lain jika pengguna telah menyediakan cdfungsi mereka sendiri atau alias untuk membebani built-in cd. Ini juga akan memverifikasi bahwa direktori saat ini masih valid dan penggunaan saat ini memiliki izin untuk berada di sana.
Kusalananda
1) tentu saja kita tidak berbicara tentang kemungkinan alias kustom "cd" tetapi standar build 2) bagaimana penggunaan saat ini dapat ada jika tidak ada izin? Sederhananya saya hanya mengatakan bahwa di dunia nyata tidak ada alasan untuk menggunakannya menurut pendapat saya.
Federico
1
1) bukan? 2) Dunia nyata tidak sederhana, dan Unix adalah sistem operasi multi-pengguna. Seorang pengguna dapat mengubah izin pada direktori, dan jika skrip, atau shell interaktif dari pengguna lain, kebetulan memiliki direktori itu (atau subdirektori daripadanya) sebagai direktori kerjanya, cd .akan mengeluh.
Kusalananda
4
Federico, sesuai dengan aturan situs dan aturan pribadi saya sendiri, saya harus menurunkan jawaban Anda. Namun, Anda baru. Selamat datang! Harap tinjau beberapa jawaban lain . Setelah itu, jika menurut Anda jawaban Anda salah, harap hapus. Silakan nikmati jawaban lain untuk pertanyaan ini dan lainnya.
daveloyall
2
Terutama dalam scripting, kadang-kadang "tidak melakukan apa-apa" adalah apa yang dibutuhkan.
Matius Najmon