Geçerli dizinde bir program çalıştırmadan önce neden `. /` Yazmam gerekiyor?


92

Bir C programını yürütürken a.out, Ubuntu terminalini kullanarak, neden sadece yazmak yerine her zaman ./önce a.outyazmam gerekir a.out? Bunun için bir çözüm var mı?




Yanıtlar:


119

a.outSistem gibi bir programın adını yazdığınızda PATH'nizdeki dosyayı arar. Benim sistemimde, PATH

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Seninki muhtemelen benzer. Kontrol etmek için echo $PATHbir terminal girin .

Sistem bu dizinlere verilen sıra ile bakar ve bulamazsa, program bir command not foundhata üretir .

Komutu ./etkin bir şekilde hazırlamak "YOLU unut, sadece şu anki dizine bakmanı istiyorum" diyor.

Benzer şekilde, komutu aşağıdaki gibi göreceli veya mutlak bir yolla hazırlayarak sisteme yalnızca belirli bir konuma bakmasını söyleyebilirsiniz:

../üst dizindeki araç anlamına gelir; örneğin, üst dizinde ../hellomerhaba arayın.

./Debug/hello: " helloGeçerli dizimin Debug alt dizininde arayın ."

veya /bin/ls: " lsdizinde ara /bin"

Varsayılan olarak, geçerli dizin yolda değildir, çünkü bu bir güvenlik riskidir. Neden olduğunu görün . varsayılan olarak yolda değil misiniz? Süper kullanıcı için neden.

Geçerli dizini PATH'inize eklemek mümkündür, ancak bağlantılı soruda verilen nedenlerden dolayı bunu tavsiye etmem.


25
Bu. +1 etmeyin eklemek .adresinden Müşteri PATH(diğer 2 cevaplar şu anda önerdiği gibi) nedeniyle bu cevapta belirtildiği güvenlik riskine.
Gün

8
Aynı zamanda ilgili özel bir şey olduğunu dikkati olabilir .yürütülebilir bir örneğin tam veya göreli yolu kullanabilir, burada /home/user/foo/a.outya./build/a.out
tobyodavies

@tobyodavies; Aslında .özeldir çünkü "şu anki dizinim" anlamına gelir ve kullanıcının okuma ve çalıştırma ayrıcalıklarıyla kendilerini bulabildiği herhangi bir dizin olabilir. Bu, belirli bir tam nitelikli yolu eklemekten potansiyel olarak daha tehlikelidir.
Warren Hill,

@WarrenHill kendi yoluna ekleyerek düşünürken, evet oldukça farklı. Ancak bash sözdizimi açısından, .böylesi daha iyi başlayabiliriz sadece bir yol, hiçbir özel statü tutan /ve ./blahsadece de çalışmak catveya grepbir bash isteminde olarak.
tobyodavies

@tobyodavies: Tamam Yanıtınızı eklemek için cevabımı düzenledim.
Warren Hill

24

Bunun nedeni basit.

Geçerli dizindeki bir uygulamayla aynı ada sahip bir komutunuz olduğunu varsayalım. Daha sonra komutu kabukta çalıştırmak, yerleşik komut yerine uygulamanızı çağırır . Başka bir şey olmazsa, bu bir güvenlik endişesi olacaktır.

./Önde kullanılmasını gerektiren kabuk, uygulamayı bu adla yerleşik bir komutla değil, verilen adla yürütmek istediğinizi bilir.


1
açıklamanız yanıltıcı, kabuktaki yerleşik komutlar ile PATH değişkeni ile erişilebilen yürütülebilir dosyalar arasında bir fark var. Aslında cevabınız ne kadar çok okursam o kadar yanlış hissettirir.
Ahmed Masud

16

./içinde olmayan dosyaları $PATHçalıştırır, dosyayı geçerli dizinde (veya başka bir yolla ./home/stefano/script.sh) çalıştırır. Şimdi PATH, bash'ın çalıştırılabilir programları arayabileceği, bunlara tam (mutlak) bir yol girmeden tüm yerleri içeren bir ortam değişkenidir.

Bu dosyanın yanlış çalışmasını önlemek için gereklidir. Yani ls, ana dizininizde adı verilen bir dosyanız varsa , PATH'inizde bulunmamak bash ile gerçek olanın karışmasını önler ls. PATH değişkeni ayrıca arama sırasını tanımlar:

  • Bir komut çalıştırdığınızda veya bir program bir execçağrı yapmaya çalıştığında (Çekirdeğin özel bir yöntemi, programların nasıl başlatıldığı), sistem PATH'nizdeki her bir dizini gözden geçirerek dosyayı arar. Program bulunduktan sonra, birden fazla klasörde olsa bile, arama durdurulur ve ilk bulunan çalıştırılır.

Bir dosyayı çalıştırmak için çalıştırılabilir biti izinlerde ayarlamanız gerekir:

  • Zaten komut satırında olduğunuzdan, sadece yazabilirsiniz chmod +x finename.

  • Veya izinleri dosyayı sağ tıklatarak ve Özellikler'i seçerek ayarlayabilirsiniz :

    alt metin

Şimdi dosyayı, PATH içindeki dizinlerden herhangi birine kopyalayabilir, hangilerinin orada olduğunu ve kullanıcı bazında ayarlandıklarını görebilirsiniz echo $PATH.

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Yürütülebilir bir dosya oluşturup catonu taşırsanız /usr/local/sbin, içinde uygun catolanın yerine çalıştırılır /bin. Dosyalarınızı kullanarak nerede öğrenebilirsiniz type catve whereis cat.


2
Unutulmaması gereken bir şey: sorusu gcc, yürütme bitini otomatik olarak ayarlayan bir şeyi derlediğini ve ilişkilendirdiğini gösteriyor .
Nathan Osman

12

./Bir programı yürütmeden önce neden yazmaya ihtiyacınız var ?

Terminalde, bir uygulamanın adını ne zaman yazsanız, diyelim ki geditterminal uygulamaları içeren (önceden tanımlanmış) dizinlere bakacaktır (uygulamaların ikilileri). Bu dizinlerin isimleri denilen bir değişkende bulunur PATH. Bu değişkende ne olduğunu çalıştırarak görebilirsiniz echo $PATH. Bu rehberler ile ayrılmış bakın :? Bunlar uç sadece yazarsanız, arama gidecek dizinleri vardır gedit, nautilusya a.out. Gördüğünüz gibi, a.outprogramın yolu orada değil. Bunu yaptığınızda ./a.out, terminale "şu anki dizine bakın ve çalıştırın a.outve içeri bakmayın PATH.

1. Çözüm

./Her seferinde yazmak istemiyorsanız , a.outdizinini de eklemeniz gerekir $PATH. Aşağıdaki talimatlarda, yolun doğru a.outolduğunu kabul edeceğim /path/to/programs/, ancak onu gerçek yolunuzla değiştirmelisiniz.

  1. Dosyanın sonuna aşağıdaki satırı eklemeniz yeterlidir ~/.pam_environment:

    PATH DEFAULT=${PATH}:/path/to/programs

    Kaynak: Kalıcı çevre değişkenleri

  2. Çıkış yapın ve tekrar giriş yapın. Artık herhangi bir dizinden çalışmadan a.outçalışabileceksiniz ./.

Başka dizinlerde başka programlarınız varsa, bunları sadece yukarıdaki satıra ekleyebilirsiniz. Ancak, örneğin "myPrograms" adlı bir dizine sahip olmanızı ve tüm programlarınızı altına koymanızı öneririm.

2. Çözüm

Not: değiştirmek userNamegerçek Ubuntu kullanıcı adına.

Ya çalıştırmak istediğiniz başka programlarınız varsa? Ve hepsi farklı klasörlerde mi? Eh, "daha organize" bir çözüm binHome dizininizin altında bir klasör oluşturmak ve bu klasörün altına sembolik bağlantılar (kısayollar) eklemek olacaktır. İşte nasıl:

  1. mkdir /home/userName/bin

    • Bu, binGiriş dizininizin altındaki klasörü oluşturur .
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • Bu, a.outprogramınızın altında "sembolik bir bağlantı" (temel olarak bir kısayol) yaratacaktır bin.
  3. Çıkış yapın ve tekrar giriş yapın. Artık herhangi bir dizinden çalışmadan a.outçalışabileceksiniz ./.

Şimdi, başka bir yerde ne zaman başka bir programınız varsa, diyelim ki b.inMasaüstünüzdeki programı , yapmanız gereken tek şey: ln -s /home/userName/Desktop/b.in /home/userName/binve daha sonra programı çalıştıramazsınız ./.

Not: @ Joe'nun yorumu sayesinde , yedekleme yaparken sembolik bağlantıların özel olarak ele alınması gerekir. Varsayılan olarak, rsynconları hiç işlemez, bu nedenle geri yüklediğinizde orada olmazlar.


1
Bu, az miktarda kullanılırsa kullanışlı bir numaradır. Çok kullanmak, sisteminizin başkalarının beklemeyeceği şeyleri yapmasını sağlar. Ayrıca, yedekleme yaptığınızda, sembolik bağlantıların özel olarak ele alınması gerekir. Varsayılan olarak , rsync onları işlemez, bu yüzden geri yüklediğinizde orada olmazlar.
Joe,

1

George'un cevabında işaret ettiği gibi, bu , geçerli çalışma dizininde ( ) bir dosyayı çalıştırdığınızı not etmenize yardımcı olur pwd.

Ben önce benim kıdemli uzun zamandır bu soruyu soran hatırlıyorum, o ben eklemek gerektiğini söyledi .yaptığımda böylece benim yoluna a.outgeçerli dizinde arar ve bu yürütür. Bu durumda yapmak zorunda değilim ./a.out.

Ancak, şahsen buna karşı öneriyorum. Bana asla olmadı, ama yabancı bir ağ dizinindeyseniz veya lsorada adı geçen kötü amaçlı bir çalıştırılabilir dosya varsa, yolunuzda olması .çok kötü bir fikirdir. Sadece bu soruna sıkça rastlayacağınızı değil, sadece söyleyerek.


tamam, Stefano bu bilgiyi içermek için cevabını kabul etti :)
Shrikant Sharat

3
Tamamen ekleyerek değil katılıyorum .için $PATH. Çok tehlikeli bir fikir.
Nathan Osman

1

Diğer cevaplara ek olarak, burada bu konuyu man bashiyi açıklayan temel kısım :

KOMUTANLI YÜRÜTME
       Bir komut kelimelerle bölündükten sonra, basit bir sonuç verirse
       komut ve isteğe bağlı bir argüman listesi
       alınmış.

       Komut adında eğik çizgi yoksa, kabuk bulmaya çalışır
       o. Bu ada sahip bir kabuk işlevi varsa, bu işlev
       FONKSİYONLAR'da yukarıda açıklandığı gibi çağrılır. İsim eşleşmiyorsa
       işlevi, kabuk, kabuk yerleşik listesi listesinde arar. Eğer
       bir eşleşme bulunur, bu yerleşik çağrılır.

       Ad, bir kabuk işlevi veya bir yerleşik değil ise,
       eğik çizgi, bash PATH öğesinin her öğesini con dizini için arar.
       bu ada göre çalıştırılabilir bir dosyayı etiketlemek.

0

Bir './' sizin için bilinen ve belirli bir programı, örneğin kendi programınızı çalıştırdığınızda anlamlıdır. Bu program mevcut dizinde bulunmalıdır. $ PATH içindeki bir yerde standart bir komut çalıştırdığınızda './' bir anlam ifade etmiyor. "Hangi komuttan çalıştırma" komutu size hangi komutun çalıştırılacağını $ PATH içinde gösterir.


0
$ gcc hello.c -o /path/to/someplace/hello

bazı yerlerde bir çalıştırılabilir dosya üretecek. Bu konum yolunuzdaysa, dosyayı çalıştırabilirsiniz. "Gcc kullanarak bu kaynak kodunu derleyin ve yolundaki bir yere bir çalıştırılabilir dosya yerleştirin" eylemi için bir etiket oluşturmak istiyorsanız bunu yazabilirsiniz.

"Testbin" ya da bu tür bir şey adı verilen yeni bir dizin oluşturmanızı ve mevcut yol dizinlerinizi temiz tutmak için yolunuza koymanızı öneririm.


0

./yol için gereksiz aramaları engeller. ./Sadece geçerli dizinde aramaya zorla. Biz vermezsem ./o zaman böyle sisteme set çeşitli yolunu arayacaktır /usr/bin, /usr/sbin/vb


0

"./", geçerli dizindeki bir dosyayı yürütmek istediğinizi, bu yolun tamamını yazmak için bir kısayol olduğunu belirtir.

[root@server ~]#/path/to/file/file.pl

aynıdır:

[root@server file]#./file.pl

önceki örnekte dizini ve alt dizinlerini dosya konumuna getirdiniz ve dosyayı geçerli dizinde çalıştırmak için "./" kullandınız.

ondan önceki " [root @ server ~] # / path / to / file / file.pl " ayrıca, dosya konumuna giderken yolunuz "cd" ye tembelseniz de dosyayı çalıştıracaktır.


-4

Çok basit ve birçok kullanım alanı var.

  1. Aynı uygulamanın birden fazla sürümü yüklendiğinde, farklı yollarda kullanılabilir ancak ikili sisteminize yumuşak bir bağlantı oluşturulabilir /usr/bin. Örneğin, Python 2.7, Python 2.6 kurulur ancak / usr / bin / python -> python2.7 / usr / yerel / bin / python -> python2.6

Yolun /usr/local/biniçindeyseniz ve Python'u çalıştırırsanız, daima Python 2.7'yi çalıştırır. Belirtilmesi ., geçerli klasörün yürütülebilir dosyasını alacaktır.

  1. .- daima geçerli dizinden yürütmeyi temsil eder. Ve ..her zaman önceki dizinden yürütür anlamına gelir.
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.