PATH araması simgeleri içerir mi?


9

POSIX kabuk standardı bu sitede diyor

http://pubs.opengroup.org/onlinepubs/9699919799/

mermilerin PATHyürütülebilir dosyaları aramak için nasıl kullandığı hakkında :

Msgstr "Belirtilen ada ve uygun yürütme izinlerine sahip yürütülebilir bir dosya bulunana kadar liste her bir önek için dosya adı uygulanarak baştan sona aranacaktır."

Eh, bu gerçek POSIX uygulamasında böyle görünmüyor:

man which diyor:

msgstr "" "" ifadeleri, geçerli bir ortamda yürütülecek dosyaların (veya bağlantıların) yol adlarını döndürür, argümanları kesinlikle POSIX uyumlu bir kabukta komutlar olarak verilmişti. Bunu, PATH'yi Sembolik bağlantıları takip etmiyor. "

Tamam, şu duruma bakalım:

$ pwd /home/mark

$ echo $PATH /home/mark/bin:...

$ ls -l bin/foobar
lrwxrwxrwx 1 mark mark 18 Dec 12 22:51 bin/foobar -> /home/mark/foobar1
$ touch foobar1
$ which foobar
$ chmod a+x foobar1
$ which foobar
/home/mark/bin/foobar

Tamam, burada PATHdoğru adla sembolik bir bağlantı var ve çalıştırılabilir olduğu bildiriliyor ls.

which hiç bakmıyor, sadece neyi işaret ettiği ile ilgileniyor.

Her ikisinin de man whichaçıkça sembolik bağlantıları takip etmediğini (ve aslında görmediğini, çünkü which foobaryazdırmadığını foobar1) ve aynı zamanda yukarıda belirtilen POSIX kabuk belgelerinin PATHalgoritmada sembollerden sonra asla bahsetmediğine rağmen .

Peki whichve mevcut mermiler yanlış mı yoksa belgeleri anlamıyorum mı?

NETLEŞTİRMEK İÇİN:

Mevcut davranışı bilir ve açıklayabilirim. Sorum "bu nasıl çalışıyor?" Değil. Bunu biliyorum.

Benim sorum dokümanlarla ilgili: alıntıladığım dokümanları takip etme konusundaki hatam nerede. Yoksa dokümantasyon yanlış mı?

MOTİVASYON: Neden umursuyorum?

Ben bir uygulayıcıyım. Farklı uygulayıcıların farklı gereksinimleri vardır. Benim için şart, mevcut POSIX standardının kelimesinin TAM OLARAK (veya daha doğrusu, en iyisi olabileceğinden, ZORUNLU) takip edilmesi GEREKİR. Tıpkı Tanrı'nın sözü gibi.

Şimdi, standart ifadeler oldukça açıktır - aşağıdaki sembollerden bahsedilmemektedir, diğer birçok yerde nerede yapılması gerektiği belirtilmektedir. Bu durumda, yapma.

Ancak, emin olmak için her zaman nasıl dashve bashdavranış yaptığımı iki kez kontrol ederim . Tabii ki, burada da küçük bir sorun var, dashPOSIX olarak faturalandırılsa bile, POSIX'e uygun birçok küçük hata var. bash, POSIX ile ilgili herhangi bir hata bulamadım, ama ... bash aslında POSIX değil, bundan çok daha fazlası.

İşte burada. Bu yüzden umursuyorum.


Anlamıyorsunuz: dosyalar üzerindeki sembolik bağlantıları takip etmiyor . $PATHsembolik semboller içerebilir. Deneyin which sh.
Ipor Sircer

Tamam ama, benim durumumda $PATHherhangi bir sembolik bağ yok.
user322908

Hemen hemen her durumda, semboller şeffaf bir şekilde takip edilir. Takip edilmedikleri durumlar genellikle açıkça belirtilir (örn. Sistem çağrıları gibi lstat(2)), bunları takip etmek genellikle belirtilmez. Örneğin, open(2)sadece tanımı , davranışlarından bahsederken sembolik bağlantılardan bahseder O_CREAT | O_EXCL. Hedef dosyanın açılacağını belirtmeye gerek yoktur.
Barmar

Yanıtlar:


10

Symlink'in izinleri önemsizdir. Denediyseniz bile onları değiştiremezdiniz.

Önemli olan temel dosyanın izinleridir.

PATH'nizdeki dizinlerin yürütülebilir dosyalar için semboller içermesi iyidir. Aslında, PATH'nizdeki birçok yürütülebilir dosyanın sembolik olması muhtemeldir. Örneğin, debian / ubuntu benzeri sistemlerde:

$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 23  2017 /bin/sh -> dash

belgeleme

Gönderen man chmod:

chmod, sembolik bağlantıların izinlerini hiçbir zaman değiştirmez; chmod sistem çağrısı izinlerini değiştiremez. Sembolik bağlantıların izinleri asla kullanılmadığından bu bir sorun oluşturmaz . Ancak, komut satırında listelenen her sembolik bağlantı için chmod, sivri uçtaki dosyanın izinlerini değiştirir. Buna karşılık, chmod, özyinelemeli dizin geçişleri sırasında karşılaşılan sembolik bağlantıları yoksayar. [Vurgu eklendi.]

Misal

Kabuk, -xbir dosyanın yürütülebilir olup olmadığını belirlemek için bir sınamasına sahiptir . Şunu deneyelim:

$ ls -l
total 0
lrwxrwxrwx 1 john1024 john1024 7 Dec 12 23:36 foo -> foobar1
-rw-rw---- 1 john1024 john1024 0 Dec 12 23:36 foobar1
$ [ -x foo ] && echo foo is executable
$ chmod +x foobar1
$ [ -x foo ] && echo foo is executable
foo is executable

Yani, tıpkı bulduğunuz gibi which, temel dosya yürütülebilir olmadığı sürece kabuk bir softlink çalıştırılabilir dosyası olarak kabul etmez.

Hangisi nasıl çalışıyor

Debian sisteminde whichbir kabuk betiğidir. Kodun ilgili bölümü:

 case $PROGRAM in
  */*)
   if [ -f "$PROGRAM" ] && [ -x "$PROGRAM" ]; then
    puts "$PROGRAM"
    RET=0
   fi
   ;;
  *)
   for ELEMENT in $PATH; do
    if [ -z "$ELEMENT" ]; then
     ELEMENT=.
    fi
    if [ -f "$ELEMENT/$PROGRAM" ] && [ -x "$ELEMENT/$PROGRAM" ]; then
     puts "$ELEMENT/$PROGRAM"
     RET=0
     [ "$ALLMATCHES" -eq 1 ] || break
    fi
   done
   ;;
 esac

Gördüğünüz gibi -x, bir dosyanın yürütülebilir olduğunu belirlemek için testi kullanır .

POSIX -xtesti aşağıdaki gibi belirtir :

-x pathname Yol adı
, dosyayı okuma, yazma ve oluşturma işlemlerinde tanımlandığı şekilde , dosyayı yürütme izninin (veya bir dizinse arama yapmanın) izni olan bir dosya için varolan bir dizin girişine çözümlenirse doğrudur . Yol adı çözümlenemiyorsa veya yol adı, dosyayı yürütme (veya arama) izni verilmeyen bir dosya için varolan bir dizin girişine çözümlenirse yanlıştır. [Vurgu eklendi.]

POSIX, yol adının neyi çözdüğünü kontrol eder . Başka bir deyişle, sembolik bağları kabul eder.

POSIX yürütme işlevi

POSIX exec fonksiyonu sembolik izler. POSIX özellikleri, sembol bağlantılarının dairesel veya çok derin olup olmadığını bildirebilecek hata koşullarını belirtmek için uzun süre devam eder, örneğin:

[ELOOP]
Yol veya dosya bağımsız değişkeninin çözümlenmesi sırasında karşılaşılan sembolik bağlantılarda bir döngü var.

[ELOOP]
Yol veya dosya bağımsız değişkeninin çözümü sırasında {SYMLOOP_MAX} taneden fazla sembolik bağlantıyla karşılaşıldı.
[ENAMETOOLONG]
Yol bağımsız değişkeninin çözünürlüğünde sembolik bir bağlantıyla karşılaşmanın bir sonucu olarak, ikame edilmiş yol adı dizesinin uzunluğu {PATH_MAX} değerini aştı.


Cevabınıza yazdığınız her şeyi biliyorum. İşlerin nasıl çalıştığını biliyorum. Benim sorum bu değil. Benim sorum dokümantasyon hakkında. Bana belgeyi anlamadığım yeri göster. Veya bana belgelerin yanlış olduğunu söyleyin.
user322908

@ user322908 Çoğu sistemde whichbir kabuk betiğidir. Bu yüzden, muhtemelen -xgösterdiğim testi kullanıyorum . POSIX'e göre, -xbir dosyanın yürütülebilir dosyaya "çözülüp çözülmediğini" test eder. Farklı bir şey görüyorsanız, nereye bakıyorsunuz?
John1024

Teşekkür ederim ve böyle bir acı olduğum için özür dilerim ... Sorumun% 99 sorudan farklı olduğunu fark ediyorum, bu yüzden neyin peşinde olduğumu anlamak zor. Yine, "nasıl" whichişe ya da bunun -xya da başka bir şeye ilgi duymuyorum . Alıntıladığım belgeleri nerede doğru takip etmediğimi bilmek istiyorum.
user322908

4
@ user322908 POSIX execişlevi sembolik bağlantıları izler. Bu, sembolik dosyaların POSIX altında yürütülebilir dosyalar olabileceğini açıkça göstermektedir.
John1024

2
Ayrıca "Yol adlarını standartlaştırmaz" yazan Ubuntu 17.10'u man which da kontrol ettim . Bu, bağlantıları takip etmediği anlamına gelmez. Bu sadece gözlemlediğiniz gibi isimleri "kanonikleştirmediği" anlamına gelir.
John1024

3

Bu durumda, semboller son yolu standartlaştırmadan şeffaf bir şekilde takip edilir . Başka bir deyişle, bir sembolik bağlantı whicholup olmadığı /home/mark/binönemli değildir. Önem verdiği şey dosyanın /home/mark/bin/foobarvar olup olmadığıdır. Bu ihtiyacı yok yol boyunca elle düzleştirmek sembolik için - OS kendi başına bu sadece para cezası yapabilirsiniz.

Ve aslında, whichdosya bilgileri sorulduğunda /home/mark/bin/foobar, işletim sistemi /home/mark/binbir sembolik olduğunu fark eder , izler foobarve hedef dizinde başarıyla bulur .

Program , dosyaya erişmek open(…, O_NOFOLLOW)veya fstatat(…, AT_SYMLINK_NOFOLLOW)bu dosyaya erişmek için kullanılmadıkça varsayılan davranıştır .

[yorum birleştirildi]

O kabuk programları bir vaka ile ayrı ayrı bunu söylemek olsa da, çekirdek sistem çağrıları ile aynı değildir: tüm dosya alakalı aramalar yapmak "nofollow" bayrağı verilmediği takdirde, varsayılan olarak sembolik izleyin. (Lstat bile sonuncusu dışındaki tüm yol bileşenlerindeki sembolik bağlantıları izler.)

Spesifikasyon, sembolik linklerle ne yapılacağını açıkça belirtmediğinde, varsayılan davranışın kullanılacağını ima eder. Olduğunu, elle yol algoritması neithers çözmek sembolik izleyen bir kabuk ne de açıkça aynı şeyi OS'nin çıkma gelmez. (Sadece her $ PATH bileşenini yürütülebilir adla birleştirir.)

Hangi (1) kılavuz sayfası sembolik bağlantıları takip etmediğini söylediğinde, birkaç anlama gelebilir, ancak GNU coreutils sürümü bunu şöyle ifade eder:

Bunlardan biri sembolik bağlantıya sahip bir yol içerdiğinde, iki eşdeğer dizinin farklı olduğunu düşünecektir.

Bu kapsam açısından çok daha dar - sadece kopyaları ayıklamak için tüm yolları el ile kanonikleştirmeye whichçalışmak anlamına gelmez, ancak aracın genel olarak işletim sistemi tarafından takip edilen sembolik bağlantıyı devre dışı bırakacağı anlamına gelmez. Örneğin, simgesine bir bağlantı varsa , çalıştırma hem ve öğelerini döndürür ./bin/usr/binwhich -a sh /bin/sh/usr/bin/sh


Evet teşekkür ederim, hepsini biliyorum. Sorum şu, işlerin nasıl işlediği değil. Nasıl çalıştıklarını biliyorum. Demek istediğim bu değil. Demek istediğim dokümantasyon hakkında. Belgeleri nerede yanlış takip ediyorum. Yoksa dokümantasyon yanlış mı?
user322908

2
Belgeleri yanlış anlıyorsunuz - aşağıdaki sembolik bağlantılardan bahsetmiyorsa , sembolik bağlantıları manuel olarak çözmediği anlamına gelir , ancak normal işletim sistemi davranışı hala geçerlidir. GNU whichmanuel sayfası bunu farklı bir şekilde ifade eder: "Bunlardan biri sembolik bağlantıya sahip bir yol içerdiğinde iki eşdeğer dizinin farklı olacağını düşünür."
user1686

Tamam, bu daha iyi teşekkürler! Anlamaya çalışıyorum ... Ama ... boyunda bir acı olmamı affedin: "düzenli OS davranışı" her zaman dolaylı olarak sembolik bağlantıları takip etmek DEĞİLDİR. Pek çok yardımcı program yok. Her durum için ayrı ayrı.
user322908

1
Tüm çekirdek çağrıları - chdir, open, chmod, execve ... - AT_SYMLINK_NOFOLLOW veya benzerlerini belirtmediğiniz sürece , hem yolda hem de kuyrukta sembol bağlantılarını izler. (lstat, kuyrukta sembolik bağlantıları yok eden, ancak yine de kalan yol için bunu yapan tek durumdur.) Bu nedenle, varsayılan davranış, sembolik bağları takip etmektir. Örneğin, bir kabuk çağırdığında execve("/home/mark/bin/foobar", …)tüm semboller takip edilir.
user1686

Tamam sanırım execveargümanı satın alıyorum , aslında benim uygulamamda da execl()aynı şey. Lütfen bunu cevabınıza dahil ederseniz kabul edeceğim.
user322908

1

Kabuk, yol adı çözümlemesi kurallarına uyması nedeniyle belgelerine uygundur. whichbelgelerine uygundur. İkisi biraz farklı şeyler yapar.

Simgesinin çıktısı which, bağlantının işaret ettiği yol değil, bağlantının dosya adı ve yoludur. Bu, kılavuz sayfasında belirtilmiştir.

Bir komut yürütüldüğünde, bağlantı aynı Bölüm 4.13 Yol Adı Çözümlemesine göre "takip edilir" . Bir dosyayı yürütmek için ilgili madde:

Diğer tüm durumlarda sistem, eğer varsa, kalan yol adını sembolik bağlantının içeriğiyle ön ekleyecektir, ancak sembolik bağlantının içeriği boş dize ise, her iki yol adı çözümlemesi bir [ENOENT] bildiren işlevlerle başarısız olacaktır. ] sembolik bağın içeriği yerine eşdeğer bir tanı mesajı yazan hata ve yardımcı programlar ya da sembolik bağlantıyı içeren dizinin yol adı kullanılacaktır. Sembolik bağlantının içeriği yalnızca karakterlerden oluşuyorsa, kalan yol adının tüm önde gelen karakterleri, elde edilen birleşik yol adından çıkarılır ve yalnızca sembolik bağlantı içeriklerinden baştaki karakterler bırakılır. Ön ekin oluştuğu durumlarda, birleştirilmiş uzunluk {PATH_MAX} değerini aşarsa ve uygulama bunu bir hata olarak görürse, [ENAMETOOLONG] hatasını bildiren işlevler ve eşdeğer bir tanılama mesajı yazan yardımcı programlar için yol adı çözümlemesi başarısız olur. Aksi takdirde, çözümlenen yol adı yeni oluşturulan yol adının çözümlemesi olacaktır. Ortaya çıkan yol adı a ile başlamazsa, yol adının ilk dosya adının öncülü sembolik bağlantıyı içeren dizin olarak alınır.

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.