Di server saya, saya memiliki struktur direktori yang terlihat seperti ini:
/myproject/code
Saya biasanya memiliki koneksi ssh ke server dan 'berdiri' di direktori itu:
root@machine:/myproject/code#
Ketika saya menggunakan versi baru kode saya, direktori kode dihapus jadi saya pergi dengan:
root@machine:/myproject/code# ./run
-bash: ./run: No such file or directory
Dan satu-satunya solusi yang saya temukan adalah keluar dan masuk kembali:
root@machine:/myproject/code# cd ../code
root@machine:/myproject/code# ./run
Running...
Bisakah saya menghindari ini? Itu perilaku yang agak aneh. Jika Anda memiliki penjelasan yang bagus mengapa ini terjadi, saya akan sangat menghargainya.
shell
command-line
directory
cd-command
Markus Johansson
sumber
sumber
run
sama dengan direktori yang lama. Hanya memiliki nama dan direktori induk yang sama. Bandingkan ini dengan merobek-robek mobil lama Anda dan membeli mobil baru dengan warna dan model yang sama persis: Anda tidak ingin duduk di dalam mobil yang tercabik-cabik dan berharap Anda berakhir dengan yang baru tanpa terluka, bukan?cd ../code
bukan noop...
adalah jalan pintas untuk induk jalur yang Anda miliki, atau dulu Anda miliki. Jika direktori Anda saat ini dihapus, jalur induk mungkin masih ada, dan dalam hal ini dapat dijangkau dengan mengevaluasi..
. Dalam direktori itu pencarian dilakukan untuk direktori dengan nama 'kode'.Jawaban:
Karena file dan direktori pada dasarnya adalah inode sistem file , bukan nama - ini mungkin detail implementasi yang spesifik untuk tipe sistem file, tetapi itu berlaku untuk semua sistem ext, jadi saya akan tetap menggunakannya di sini.
Ketika direktori baru
code
dibuat, itu terkait dengan inode baru, dan di situlah tempatnya. Tidak ada catatan tentang file dan direktori yang dihapus sebelumnya, sehingga tidak ada cara yang digunakan sistem untuk memeriksa inode apa yang digunakannya untuk ditempati dan mungkin mengaduk-aduk sekitar sehingga sama lagi; sistem seperti itu akan dengan cepat menjadi tidak bisa dijalankan, dan dalam hal apapun, itu mungkin bukan jaminan bahwa Anda akan kembali ke sana lagi - itu akan menjadi semacam yang tidak diinginkan, karena itu berarti Anda juga bisa secara tidak sengaja berakhir di tempat lain jika direktori dibuat yang mengambil inode Anda (saat ini tidak digunakan).Saya tidak yakin apakah kemungkinan terakhir ini ada, atau apakah inode dari direktori yang dihapus saat ini ditugaskan untuk direktori kerja Anda saat ini dilacak sehingga tidak ada yang akan ditugaskan untuk itu selama durasi, dll.
sumber
Kulitmu Anda tidak setiap kali melakukan a
cd
ke path yang ada di selama perintah terakhir, sebelum menjalankan perintah berikutnya.Anda menghapus direktori saat ini dan membuat direktori dengan nama yang sama, yang bukan direktori yang sama, hanya sesuatu dengan nama / jalur yang sama.
Browser file seperti Nautilus dan Windows Explorer biasanya "naik" pohon direktori jika direktori terhapus pada sistem file lokal. Namun ini tidak selalu benar untuk sistem file jaringan, dalam hal ini kadang-kadang penghapusan tidak diperhatikan dan kemunculan kembali bisa membuat Anda berakhir di direktori baru.
Sebuah shell dapat
cd
masuk ke direktori saat ini sebelum menjalankan perintah berikutnya, saya tidak mengetahui ada yang melakukan (atau dapat dikonfigurasi untuk melakukannya).sumber
Pada kebanyakan sistem mirip UNIX, "direktori saat ini" untuk suatu proses disimpan dalam kernel sebagai deskriptor file yang menunjuk ke direktori itu. Kernel sebenarnya tidak menyimpan path direktori saat ini: informasi tersebut dilacak oleh shell Anda.
Objek filesystem (file atau direktori) hanya dihancurkan untuk selamanya ketika semua tautan filesystem ke sana, dan tidak ada deskriptor file yang menunjuk ke objek tersebut.
Jadi, jika suatu direktori dihapus ketika masih ada proses yang menahannya sebagai direktori kerjanya saat ini, prosesnya
cwd
akan menjaga direktori tersebut tidak benar-benar dihapus. Tautan filesystem yang menjangkar direktori (entri di direktori induk, dan semua isinya) akan hilang, tetapi direktori itu sendiri akan terus ada sebagai semacam "zombie". Sementara itu, Anda dapat membuat direktori baru di lokasi yang sama dengan yang lama, yang merupakan objek sistem file yang sama sekali berbeda tetapi berbagi jalur yang sama.Jadi, ketika Anda melakukannya
cd ../code
(atau, pada banyak shell,cd .
), Anda sebenarnya melintasi hierarki sistem file dan pergi ke direktori baru yang berada di alamat lama.Dengan analogi, menghapus direktori akan seperti memindahkan rumah ke tempat sampah secara paksa (memutuskan hubungan dengan alamat sebelumnya). Jika masih ada seseorang yang tinggal di sana (menggunakannya sebagai milik mereka
cwd
), mereka harus pergi sebelum rumah itu bisa dihancurkan. Sementara itu, rumah baru dapat dibangun di alamat lama.sumber
@Anthon menjelaskan alasan, mengapa hal itu terjadi
Sebagai solusi, Anda dapat menggunakan alias , sebagai contoh:
alias untuk bash tetap di ~ / .bashrc
sumber
Mengkonfirmasi Direktori kerja saat ini didasarkan pada nomor inode, bukan apa yang Anda cari. Karena Anda menggunakan bash, Anda dapat menggunakan $ PWD sebagai berikut untuk melakukan cd ke direktori baru dengan nama yang sama:
cd $ PWD
Sebagai ilustrasi, saya membuat perintah dummy deploy:
Membuat penyebaran pertama, cd'd ke kode dan kemudian memeriksa konten
ls -lai
sehingga Anda dapat melihat inode:Sekarang jalankan penyebaran ke-2
Dan periksa isi direktori ... sekarang tidak ada apa pun di direktori! bahkan tidak '.' dan '..'! Dari sini Anda dapat melihat bahwa bash tidak menggunakan entri direktori '..' ketika Anda menjalankan
cd ..
sejak '..' tidak ada lagi - saya kira itu bagian dari penanganan $ PWD-nya. Beberapa shell lain / lama tidak menanganicd ..
dalam situasi ini, Anda harus cd ke jalur absolut terlebih dahulu.Cd ke
$PWD
dan coba lagi:Perhatikan bagaimana inode untuk direktori saat ini (.) Berubah?
Jika skrip deploy Anda memindahkan direktori lama ke nama lain, misalnya
mv code code.$$
dalam skrip, deploy skrip di atas, maka./run
akan berfungsi, tetapi sampai Anda menggunakancd $PWD
Anda akan menjalankan kode lama , bukan yang baru.Menyebarkan menggunakan capistrano memiliki masalah yang sama (Mereka memiliki symlink dari nama saat ini ke rilis saat ini), jadi saya menggunakan alias untuk cd ke area produksi / pementasan serta mengatur RAIL_ENV tepat:
sumber
Jalan menuju sesuatu adalah bagaimana Anda sampai di sana, bukan hal itu sendiri. Jalan menuju tempat tidur Anda mungkin melalui kamar Anda, tetapi begitu Anda berada di tempat tidur, jika seseorang mengambilnya dan membawanya keluar, Anda tidak lagi berada di kamar Anda.
sumber
Bukan jawaban yang lengkap, tetapi saya memiliki poin tambahan, yang margin komentarnya terlalu kecil untuk dikandung.
Untuk lebih memahami gagasan bahwa direktori dalam sistem file yang relevan lebih dari sekadar path, coba pindahkan direktori kerja proses lain saat ini: dalam satu shell, mulailah sesi Python interaktif:
Lalu, buka shell lain dan pindahkan direktori itu:
Kembali ke yang asli:
sumber