it-swarm-tr.com

Neden Linux / UNIX'te bir dosya yürütmek için "./" (nokta eğik çizgi) kullanıyoruz?

Linux'ta bir dosyayı yürütmek için neden ./filename Kullanıyoruz?

Neden sadece diğer komutlar gibi girmiyorum gcc, ls etc ...

89
Renjith G

Linux, UNIX ve ilgili işletim sistemlerinde . Geçerli dizini belirtir. Geçerli dizininizde bir dosya çalıştırmak istediğinizden ve bu dizin $PATH Öğenizde bulunmadığından, Shell'e yürütülebilir dosyanın nerede olduğunu bildirmek için ./ Bitine ihtiyacınız vardır. Yani ./foo, Bu dizindeki foo adlı yürütülebilir dosyayı çalıştırmak anlamına gelir.

type veya which$PATH dosyasında bulunan komutların tam yolunu bulmak için.

80
badp

Gerçek cevap diğerlerinin verdiği gibidir: çünkü geçerli dizin $PATH İçinde değil.

Ama neden? Kısacası, güvenlik için. Başkasının ana dizinine (veya/tmp) bakıyorsanız ve yalnızca gcc veya ls yazıyorsanız, kötü amaçlı sürümü değil, gerçek dizini çalıştırdığınızı bilmek istersiniz. prankster arkadaş tüm dosyalarınızı silen yazmıştır. Başka bir örnek, Shell'in yerleşik olarak yoksa, Shell komut dosyalarında bu komutları geçersiz kılabilecek test veya [ Olabilir.

Yolunuza son girişi olarak . Girilmesi biraz daha güvenlidir, ancak bundan faydalanan başka saldırılar da vardır. Kolay olan, sl veya ls-l Gibi yaygın yazım hatalarından yararlanmaktır. Veya, bu sistemde yüklü olmayan ortak bir komut bulun - vim, örneğin, sistem yöneticileri bunu yazmak için ortalamanın üzerinde bir olasılıktadır.

103
mattdm

Yani, neden başlangıçta ./'ye ihtiyacınız var - bunun nedeni (Windows'takinin aksine), geçerli dizinin varsayılan olarak yolunuzun bir parçası olmamasıdır. Eğer koşarsan:

$ ls

kabuğunuz PATH ortam değişkeninizdeki dizinlerde ls arar (echo $PATH)) ve bulduğu ls adlı ilk yürütülebilir dosyayı çalıştırır. Eğer yazarsanız:

$ a.out

kabuk da benzer şekilde çalışır - ancak muhtemelen a.out adında bir yürütülebilir dosya bulamaz. Shell'e a.out öğesinin nerede olduğunu söylemeniz gerekir - geçerli dizinde (.) Yer alırsa, yol ./a.out.

Neden "a.out" olarak adlandırıldığını soruyorsanız, bu sadece gcc için varsayılan çıktı dosyası adıdır. Bunu -o komut satırı arg ile değiştirebilirsiniz. Örneğin:

$ gcc test.c -o test
$ ./test
45
Simon Whitaker

:. $ PATH değişkeninize.

ALT + F2'yi deneyin ve şunu yazın: gksudo gedit /etc/environment Linux/GTK çalıştırıyorsanız (Ubuntu kullanıyorsanız sahip olduğunuz şey budur).

ANCAK, bunu yapmamanızı şiddetle tavsiye ederim. Kötü kötü kötü ve kötü.

Bilirsiniz, bu tür şeyler 1970'den beri böyle çalışır. Geçerli dizinin $ PATH'a dahil edilmemesinin bir nedeni vardır.

. geçerli dizindir

.something gizli bir dosya olurdu (Nautilus'ta görünmelerini sağlamak için "ALT +" yazın veya "ls -la".

./someProgram.sh, geçerli dizinde yürütülebilir birProgram.sh dosyasını çalıştırmak için yazdığınız şeydir.

.somethingElse geçerli dizinde gizli bir yürütülebilir dosya olduğu anlamına gelir, bu kötü bir fikirdir.

4
tiktak

Daha eksiksiz kural aslında: Yolda herhangi bir eğik çizgi / İse, PATH

Gerekçeye girmeden önce, öncelikle bu gerçeği bilmelisiniz:

bin/someprog

veya:

/bin/someprog

veya:

cd bin
./myexec

PATH değişkenini tam olarak aynı nedenden dolayı aramadan bin/someprog komutunu yürütün: bin/someprog, /bin/someprog ve ./someprog öğelerinin hepsinde eğik çizgi var /.

someprog tek başına eğik çizgi / içermez ve bu nedenle yalnızca PATH içinde arama yapar.

POSIX 7 şu kuralı belirtir: http: //pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01

/ POSIX PATH kuralı için gerekçe

Varsayalım:

someprog

arayacaktı:

  • önce CWD'ye göre
  • sonraki PATH ile ilgili

Ardından, dağıtımınızdan /bin/someprog Çalıştırmak istiyorsanız ve şunu yaptınız:

someprog

bazen işe yarayabilir, ancak diğerleri başarısız olur, çünkü başka bir ilgisiz someprog programı içeren bir dizinde olabilirsiniz.

Bu nedenle, yakında bunun güvenilir olmadığını öğreneceksiniz ve PATH kullanmak istediğinizde her zaman mutlak yollar kullanacaksınız, bu nedenle PATH'ın amacını yeneceksiniz.

Bu yüzden PATH'nizde göreli yollara sahip olmak gerçekten kötü bir fikirdir. Ben sana bakıyorum, node_modules/bin .

Tersine, şu koşuyu varsayalım:

./someprog

Arama:

  • önce PATH'a göre
  • sonraki CWD'ye göre

Daha sonra, bir git deposundan someprog komut dosyasını indirdiyseniz ve CWD'den çalıştırmak istiyorsanız, bunun çalıştırılacağı gerçek program olduğundan asla emin olmazsınız, çünkü belki de dağıtımınız şunları içerir:

/bin/someprog

geçen yıl Noel'den sonra çok fazla içtikten sonra kurduğunuz paketten PATH içinde.

Bu nedenle, bir kez daha, ne çalıştırdığınızı bilmek için her zaman CWD'ye göre yerel komut dosyalarını tam yollarla çalıştırmak zorunda kalacaksınız:

"$(pwd)/someprog"

bu da son derece can sıkıcı olurdu.

Gelmek isteyebileceğiniz başka bir kural:

göreli yollar yalnızca PATH, yalnızca mutlak yollar CWD kullanır

ancak bu, kullanıcıları "$(pwd)/someprog" içeren PATH olmayan komut dosyaları için her zaman mutlak yollar kullanmaya zorlar.

/ Yol arama kuralı, sorunla ilgili hatırlanması kolay bir çözüm sunar:

  • eğik çizgi: PATH kullanma
  • eğik çizgi yok: yalnızca PATH kullanın

mevcut dizindeki dosyaların ./somefile veya somefile olarak ifade edilebileceğine güvenerek, her zaman ne çalıştırdığınızı bilmenizi kolaylaştırır ve bu nedenle onlardan biri.

Bazen, PATH ile ilgili olarak some/prog İçin arama yapamayacağınız biraz can sıkıcı, ama bunun daha akılcı bir çözümünü göremiyorum.