Saya telah membuat symlink dengan path absolut ke direktori (Blink) dan memiliki pohon contoh sebagai berikut:
$ ls -l /tmp/A
total 0
lrwxrwxrwx 1 root root 6 Apr 3 12:27 Blink -> /tmp/B
-rw-r--r-- 1 root root 0 Apr 3 12:27 foo
$ ls -l /tmp/B
total 0
-rw-r--r-- 1 root root 0 Apr 3 12:27 bar
kemudian saya pergi ke / tmp / A dan mengubah direktori ke Blink:
$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink
cd ..
mengembalikan saya ke /tmp/A
tetapi jika saya mengetik misalnya ls ../foo
saya akan mendapat kesalahan:
ls: ../foo: No such file or directory
perintah cd builtin menyelesaikan path sesuai kebutuhan, tetapi ls eksternal menganggap .. sebagai up-level / tmp / B dan karenanya tidak dapat menemukan foo.
Apa masalah yang terjadi di sini? Bisakah saya mendapatkan file foo dari / tmp / A / Blink dengan jalur relatif seperti ../foo?
Jawaban:
Saya tidak berpikir Anda bisa melakukan ini. Shell sekarang melacak bagaimana mereka sampai di mana mereka berada, mereka melacak direktori kerja saat ini dengan nama, bukan hanya mengandalkan sistem file dan OS untuk menyimpannya. Itu berarti built-in
cd
dapat "mencadangkan" tautan simbolik, daripada hanya mengikuti rantai ".." secara langsung.Tetapi ketika Anda menjalankan
ls ../foo
,ls
tidak menyadari bahwa shell masuk ke direktori dengan mengikuti tautan simbolik.ls
akan melakukanstat()
pada "../foo". Bagian ".." berasal dari direktori saat ini, yang hanya memiliki satu entri ".." untuk induknya. Keseluruhan tautan simbolik tidak mengubah cara direktori memiliki satu "." dan satu entri "..". Tautan simbolik membiarkan kernel menyisipkan lapisan tipuan tambahan ke dalam jalur file. Ketika Anda meneruskan "../wh Apapun" keopen()
ataustat()
, kernel hanya menggunakan direktori kerja saat ini dari proses melakukan panggilan untuk mencari tahu direktori tunggal mana yang dinamai dengan "..".sumber
Shell menyimpan direktori kerja saat ini di
$PWD
. Itulah yang digunakan untuk shell builtincd
danpwd
, dan memperlakukan symlink sebagai direktori normal, seperti yang Anda lihat. Terkadang ini membantu, kadang tidak.Anda dapat menemukan direktori nyata menggunakan
pwd
(ketikhelp pwd
untuk lebih jelasnya):Demikian juga,
cd
memiliki opsi-P
(sekali lagi,help cd
adalah teman Anda):Akhirnya, Anda dapat mematikan "fitur" sama sekali:
sumber
set -P
dan perilaku mulai masuk akal. :)Bruce dan saya memberikan jawaban yang indah menjelaskan perilaku di belakang. Tetapi untuk benar-benar melakukan apa yang
ls ../foo
Anda minta, Anda bisa pergi dengan sesuatu sepertisumber
Anda tidak bisa melakukannya, karena
/tmp/A/Blink
ini sebenarnya/tmp/B
. Begitu,ls ../A/foo
berhasil.Alih-alih, Anda mungkin merasa berguna untuk dapat melakukan cd ke direktori yang sebenarnya
/tmp/B
, alih-alih alias/tmp/A/Blink
. Untuk melakukan itu, Anda dapat menggunakan fungsi berikut alih-alihcd
(yang dapat Anda masukkan ke .bashrc)lcd
, tentu saja, berfungsi untuk direktori normal dan simbolik terkait.Catatan:
readlink -f
bertindak atas target akhir tautan (saat tautan diikat daisy) ..sumber
cd -P
sepertinya lebih sederhana.