Bu softlink neden beklendiği gibi çalışmıyor?


11
bash4.3 # pwd
/bin
bash4.3 # ll sh
lrwxrwxrwx. 1   root    root    4   May 17 22:22 sh -> bash
bash4.3 # ll bash
-rwxr-xr-x. 1   root    root    1072056 May 17 22:22 bash
bash4.3 # bash
bash4.3 # sh
sh-4.3#

İşletim sistemim fedora 24 (Varsayılan GNOME sürümü).

Örnekten biliyoruz: under /bin, bashbir ikili çalıştırılabilir; shyumuşak bir bağlantıdır bash.

Yani, bildiklerime göre, type bash and press enteraynı sonucu aynen etkilemelidir type sh and press enter.

Ben beklediğim gibi type bash and press enterolsun [root@localhost bin]#.

Ancak, eğer ben type sh and press enter, şaşırtıcı bir şekilde alırım sh-4.3#.

Sebebi nedir?


Görüntü olarak kolayca bir SE editörüne yapıştırılabilen metin oldukça can sıkıcıdır, bu yüzden lütfen bunu yapmayın. Bunun yerine terminalinizdeki metni seçin ve CTRL-SHIFT-C tuşlarına basın.
kedi

Yanıtlar:


25

Bu belgelenmiş bir özelliktir.

Bash adlı bir symlink aracılığıyla çalıştırırsanız sh, bash shuyumluluk modunda başlar.

Gönderen man bash:

Bash sh adıyla çağrılırsa, POSIX standardına da uyurken, sh'in eski sürümlerinin başlatma davranışını mümkün olduğunca yakından taklit etmeye çalışır. Etkileşimli bir giriş kabuğu veya --login seçeneğiyle etkileşimli olmayan bir kabuk olarak çağrıldığında, önce / etc / profile ve ~ / .profile komutlarını bu sırayla okumaya ve yürütmeye çalışır. --Noprofile seçeneği bu davranışı engellemek için kullanılabilir. Sh adıyla etkileşimli bir kabuk olarak çağrıldığında, bash ENV değişkenini arar, tanımlanmışsa değerini genişletir ve genişletilmiş değeri okumak ve yürütmek için bir dosyanın adı olarak kullanır. Sh olarak çağrılan bir kabuk başka herhangi bir başlangıç ​​dosyasındaki komutları okumaya ve yürütmeye çalışmadığından, --rcfile seçeneğinin bir etkisi yoktur. Sh adıyla çağrılan etkileşimli olmayan bir kabuk, başka herhangi bir başlangıç ​​dosyasını okumaya çalışmaz. Sh olarak çağrıldığında, başlangıç ​​dosyaları okunduktan sonra bash posix moduna girer.

Bir program başlatmak için hangi adın kullanıldığını nasıl bilir?

Bir ac programı ise, inceleyebilir argv[0]. Bir kabuk veya perl betiği ise inceleyebilir $0.

Örnek olarak, bu basit kabuk komut dosyasını ele alalım:

$ cat utc
#!/bin/sh
case "${0##*/}" in
        utc) date -u ;;
        et) TZ=US/Eastern date ;;
esac

$0betiğin çağrıldığı addır. ${0##*/}herhangi bir dizin adı kaldırıldığında komut dosyasının çağrıldığı addır.

Bu symlink'i oluşturalım:

ln -s utc et

Yani, utcve ether ikisi de aynı yürütülebilir çalıştırmak ancak farklı sonuçlar sağlar. Olarak çalıştırıldığında utc, evrensel zaman verir. Olarak çalıştırıldığında et, çıktı ABD Doğu zamanı. Örneğin:

$ utc
Wed Jul 20 18:14:18 UTC 2016
$ et
Wed Jul 20 14:14:20 EDT 2016

4
OP çağrıların özdeş olmasını beklediğinden, bunun nasıl mümkün olabileceğini eklemek isteyebilirsiniz. ( argv[0], obvs)
Orbit'te Hafiflik Yarışları

@LightnessRacesinOrbit İyi fikir. Bir örnek ekledim.
John1024

Şimdi mükemmel. :)
Yörüngedeki Hafiflik Yarışları
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.