bir dizine ve göreli yola sembolik bağlantı


15

Ben dizin (Blink) mutlak yolu ile symlink oluşturduk ve örneğin aşağıdaki ağaç var:

$ 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

sonra / tmp / A'ya gidip dizini Blink olarak değiştiriyorum:

$ cd /tmp/A
$ pwd
/tmp/A
$ cd Blink
$ pwd
/tmp/A/Blink

cd ..beni döndürür, /tmp/A ancak örneğin ls ../fooyazarsanız hata alırım:

ls: ../foo: No such file or directory

yerleşik cd komutu yolu gerektiği gibi çözer, ancak harici ls .. / tmp / B'nin üst düzeyi olarak kabul edilir ve bu nedenle foo bulamaz.

Burada sorun nedir? Foo dosyasını ../foo gibi göreli yollarla / tmp / A / Blink'ten alabilir miyim?


Aynı soru üzerine çapraz gönderildiği Superuser
Peter.O

Yanıtlar:


13

Bunu yapabileceğini sanmıyorum. Günümüzde kabuklar, bulundukları yeri nasıl aldıklarını takip ediyorlar, sadece dosya sistemine ve işletim sistemine güvenmek yerine mevcut çalışma dizinini adlarına göre takip ediyorlar. Bu, yerleşik cd"doğrudan" .. "zincirlerini takip etmek yerine sembolik bağlantıyı" yedekleyebilir " anlamına gelir .

Ancak çalıştırdığınızda ls ../foo, lskabuğun sembolik bağlantıları izleyerek bir dizine geldiğinin farkında değilsiniz. lsBir yapacak stat()"../foo" konulu. ".." bölümü, üst için yalnızca tek bir ".." girdisi olan geçerli dizinden gelir. Tüm sembolik bağlantı şey dizinlerin tek bir "." ve tek bir ".." girişi. Sembolik bağlantılar, çekirdeğin dosya yollarına fazladan bir dolaylama katmanı eklemesine izin verir. "../Whatever" ifadesini open()veya öğesine ilettiğinizde stat(), çekirdek yalnızca ".." tarafından adlandırılan tek bir dizinin adını bulmak için çağrı yapan işlemin geçerli çalışma dizinini kullanır.


17

Kabuk, geçerli çalışma dizinini içinde saklar $PWD. Kabuk yapıları için kullanılan budur cdve pwdgördüğünüz gibi sembolik bağlantılara normal dizinler gibi davranır. Bazen bu yardımcı olur, bazen hayır.

Gerçek dizini pwd( help pwddaha fazla ayrıntı için yazın) komutunu kullanarak bulabilirsiniz :

$ pwd
/tmp/A/Blink
$ pwd -L
/tmp/A/Blink
$ pwd -P
/tmp/B

Benzer şekilde, cdbir seçeneği var -P(yine help cdarkadaşın):

$ cd /tmp/A/Blink
$ pwd
/tmp/A/Blink
$ cd -P ..
$ pwd -P
/tmp

Son olarak, "özelliği" tamamen kapatabilirsiniz:

$ set -P
$ cd /tmp/A/Blink
$ pwd
/tmp/B

Teşekkürler, set -P özelliği hakkında farkındayım, ama ls komut davranışı ile karıştırıldı ...
user478681

Dediğim gibi, kullanım set -Pve davranış mantıklı olmaya başlar. :)
ams

2

Bruce ve ams, arkasındaki davranışı açıklayan güzel cevaplar verdi. Ama aslında istediğin şeyi yapmak için ls ../foo,

ls $(dirname $PWD)/foo

1

Çünkü bunu yapamaz /tmp/A/Blink ise aslında /tmp/B. Yani, ls ../A/fooişe yarıyor.

Bunun yerine yararlı muktedir bulabilir cd için gerçek /tmp/B yerine başka ad daha dizindeki /tmp/A/Blink. Bunu yapmak için, aşağıdaki işlevi kullanabilirsiniz cd(.bashrc'nize koyabilirsiniz)

lcd() { cd $(readlink -f "$1"); }

lcd, tabii ki, normal ve sembolik bağlantılı dizinler için çalışır.
Not: readlink -fbağlantının nihai hedefi üzerinde çalışır (bağlantılar papatya dizimi yapıldığında).


1
cd -Pdaha basit görünüyor.
jw013

@ jw013: Haklısın; bu. Farkında değildim .. teşekkürler ..
Peter.O
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.