Sembolik bağlantımı nasıl bulabilirim?


13

Kabuğum basholarak MacOSX kullanıyorum . Ben böyle oluşturulan sembolik bir bağ var:

ln -s /usr/bin/python python2 

Python2 kullanan bir paket var ve geçerli çalışma /usr/bin/pythondizinimde aslında python2 olan bir sembol bağlantısı oluşturmak istiyorum . Ben ne zaman python2komut satırından bu hatayı alıyorum:

python2: realpath couldn't resolve "/usr/bin/python2"

Ancak bu şekilde çağırmak ./python2yolu doğru bir şekilde çözer. İçimde PATHvar .. Aslında, test için, sadece .içinde olacak şekilde değiştirdim.

Bunu nasıl çözerim? Teşekkürler!


bağlam

Aşağıdaki önerilen çözümlerden bazıları benim için çalışmaz. İnsanları bir metin denizinde boğulmamak için sorumu olabildiğince odaklanmış ve kısa bir şekilde damıtmaya çalıştım, ancak açıkça daha fazla arka plan sağlamam gerekiyor.

Git'ten klonladığım bir paket üzerinde geliştirmeye çalışıyorum. Orijinal paket, git-multimail/ Linux'un bazı varyantlarında geliştirildi / geliştirildi (sanırım Ubuntu). Mümkün olduğunca az değişiklikle MacOSX üzerinde ve test paketini kullanabilmek için değiştirmeye çalışıyorum. Önerilen çözümlerden bazıları neden ideal değil:

  1. Kök olarak, python2/ usr / bin / dizininde bir sembolik bağlantı oluşturun . Bunu gerektirmeyen bir çözüm arıyorum. Bu başlangıçta bariz bir seçimdi, ancak ana bilgisayar sistemini olabildiğince az değiştiren bir çözüm istiyorum. Bu nedenle, geçerli çalışma dizininde geçici bir symlink oluşturmak, CWD'yi (yani .) yoluma eklemek ve bitirdiğimde (yani symlink) yok etmek istedim.

  2. Mevcut python ile python komut dosyasını çağırmak için bir sarıcı komut dosyası oluşturun. Buradaki sorun, test paketinin büyük bir kısmının, doğru yürütme ortamını bulmak için shebang'a bağlı olarak gerçek script_files dosyalarını yürütülebilir olarak kullanmasıdır. Bu, test paketini önemli ölçüde düzenlemek anlamına gelir. Bu bağlamda, (test çerçevesinin bir snippet'i için aşağıya bakın), her .pydosya için bir sarıcı eklemem gerekir ; ayrıca kullanıcı / geliştirici, hangi sistemde bulunduklarına bağlı olarak paketi kullanmak için farklı kuralların farkında olmalıdır (örn. MacOSX'te, python dosyalarını sarmalayıcı aracılığıyla çağırmadan veya açıkça çağırmadan kullanmadığınızdan emin olun /usr/bin/python file.py).

    #! /bin/sh
    
    D=$(cd $(dirname "$0") && pwd)
    MULTIMAIL="$D/../git-multimail/git_multimail.py"
    POST_RECEIVE="$D/../git-multimail/post-receive"
    
    TESTREPO=$("$D/create-test-repo")
    
    HOME="$D"
    XDG_CONFIG_HOME="$D"
    GIT_CONFIG_NOSYSTEM=1
    export HOME XDG_CONFIG_HOME GIT_CONFIG_NOSYSTEM
    
    cd $TESTREPO
    
    test_email() {
        REFNAME="$1"
        OLDREV="$2"
        NEWREV="$3"
        echo "$OLDREV" "$NEWREV" "$REFNAME" | USER=pushuser "$MULTIMAIL"
    
    } 
    
  3. İle ilgili tüm python2referanslar değiştiriliyor python. README bunu önerir, ancak sistem değişikliği (anlamsal olarak) olmadığında sistem değişikliği yeni sürüm olarak gördüğünden, bu durum sürüm kontrolünü etkili bir şekilde işe yaramaz hale getirir.

(3) kullanıyorum ama daha iyi bir çözüm bulmaya çalışıyorum. Bu şeylerin sadece yol olduğunu kabul etmek istiyorum (yani 'python2' /usr/bin/pythontest paketi ve gerçek çerçeve çok fazla değişiklik olmadan taşınabilir ve mütevazi işaret için uygun bir yolu yoktur ).


1
Hey! Sadeceln -s /usr/bin/python /usr/bin/python2
enedil

Gerçekten de Linux'ta git-multimail geliştiriyorum. Ama ben OS X. BTW üzerinde çalışmak için yamalar ve test hoş geldiniz. BTW, git-multimail hem python2 hem de python3 :-) kabul gibi, şimdi "python2" sorunu çözüldü.
Matthieu Moy

Genişletilmiş soru hala önemli bir ayrıntıyı kaçırıyor: Yürütülebilir komut dosyalarındaki shebang satırı neye benziyor? İçin git-multimail.pyöyle #!/usr/bin/env python2, yani bunu yapmak için (nispeten) basit bir yolu var.
alexis

@ enedil adlı kullanıcının yorumu işe yaramadı, ancak işe ln -s /usr/bin/python2.7 /usr/local/bin/python2yaramadı
Phylliida

Yanıtlar:


3

Bir symlink'i çözmeniz (veya araştırmanız) gerekiyorsa, platformdan bağımsız bash kütüphanesi 'realpath-lib' kullanabilirsiniz. Varsayılan olarak readlink'i öykünür ve Mac veya Unix üzerinde çalışır. Bu bulunabilir Github veya Bitbucket ve ücretsiz.

Ancak yerel (çalışma) dizininizden python2 (./python2 yerine) yapmak istediğiniz anlaşılıyor. Bunu .bashrc dosyanızdaki bir diğer adla yapmak mümkün olabilir, aksi takdirde PATH ortam değişkeninize çalışma dizinini (sembolik bağınızı içeren) eklemeniz gerekir. Bu yalnızca geçerli oturum için veya .bashrc dosyası içinde gelecekteki oturumlar için de yapılabilir. Bu sadece belirli bir kullanıcı için bir çözüm olabilir.

Tüm kullanıcılar için işe yarayacak diğer bir seçenek de / usr / bin / python için / usr / local / bin gibi yoldaki başka bir dizinde python2 symlink'i oluşturmak olacaktır. Belki şöyle bir şey:

sudo ln -s /usr/bin/python /usr/local/bin/python2

Daha sonra herhangi bir kullanıcı veya komut dosyası python veya python2 komutlarını bulmalıdır. Tabii ki bu seçenek yüklemek için yönetici (kök) ayrıcalıkları gerektirir.


Sonunda vazgeçtim. Kodda 'python2' olduğu varsayılan çok fazla yer var ve her yerelleştirilmiş çözüm tüm olasılıkları kapsamıyor. Bu çivi için en uygun balyozdur.
Avery Chan

@Herhangi bir çözümümü denedin mi? Bir sorun mu vardı? Bu eklemenizi gerekli olmazdı python2için /usr/bin(Ben bir iyileştirme olarak eklemeden görünümünde olsa dürüst olmak gerekirse,).
alexis

Bunu bir takma adla yapmak mümkün olabilir (...) Takma ad komut dosyalarını değil, yalnızca komut satırını etkiler. Bkz Debian 7.5 de Python varsayılan sürümünü nasıl değiştirilir?
Piotr Dobrogost

Bu doğru cevap değil, en azından posterin soruyu sormasına neden olan sorunu çözmüyor.
smaudet

16

Aynı programın birden çok sürümünü yönetmek ve bunlar arasında geçiş yapmak için Apple'ın sistemi ile ilgili bir çalışma yürüttüğünüze inanıyorum. Aşağıdaki komut dosyasıyla istediğinizi daha az zarif ama sorunsuz bir şekilde başarabilirsiniz python2:

#!/bin/bash
exec /usr/bin/python "$@"

Yürütülebilir hale getirin ( chmod +x python2) ve işin içindesiniz.

Sorunun açıklaması:

Çalıştırdığınızda /usr/bin/python, python2.7 aynı dizinde bulur ve yürütür . Sembolik bağlantınız başarısız olur, çünkü sistem symlink'i takip eder /usr/bin, sonra arar ve orada bulamaz python2 . Sembolik bir bağlantı yerine "sabit bağlantı" kullanarak bir adım ileri gidebilirsiniz:

rm python2
ln /usr/bin/python python2

Şimdi izlenecek sembolik bir bağlantı yok, aynı dosya için iki dosya adı (inode). Ama şimdi aşağıdaki mesajla başarısız oluyorum:

python2: posix_spawn: /Users/alexis/.../python22.7: No such file or directory

Dikkat python22.7: Çerçeve, 2.7oluşturduğunuz isme ekleniyor ! Bunu çözmeye çalışmak ve beklentilerine uygun bir bağlantı ormanı kurmak yerine , sürüm yönetimi çerçevesinin dışında kalmanızı ve yukarıda önerilen çözümü kullanmanızı tavsiye ederim .

PS. Daha iyi bir çözüm olabilir: Başlamak için ne yapmanız gerektiğini açıklarsanız (neden python2takma ad olarak sağlamanız gerekir python), biri muhtemelen farklı bir şekilde yapmanıza yardımcı olabilir. Bu stackexchange lingo bir "XY sorunu" olarak bilinir ...


Çalıştırdığınızda /usr/bin/python, aynı dizinde python2.7'yi bulur ve yürütür. Bu çok kafa karıştırıcı bir ifade. /usr/bin/pythonBir symlink'in bulunduğu durumu açıklarsanız, lütfen daha spesifik olun.
Piotr Dobrogost

Bu sadece inanılmaz kötü ..
nicolas

İnanılmaz derecede kötü olan ne?
alexis

Evet burada açıkça belirtilmeyen şey, ben / usr / bin / python aslında python olmadığını düşünüyorum, sadece MacOS yüklü python (çerçeveler klasörüne symlinked python2.7) arar. @Nicolas'ın sahte python sürümünün inanılmaz kötü olduğunu söylediğinden şüpheleniyorum - bu oldukça hack ve Apple'ın bunu yapmamış olmasını dilerdim. ... Apple'ın yapmasını istemediğim pek çok şey var ki bu da başka türlü iyi Unix sistemiyle doluydu.
smaudet

3

Deneyin:

ln -s /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /usr/local/bin/python2

1
Neden vahşileştiğini bilmiyorum, bu benim için çalışan tek çözüm
xApple

1

readlinkBağlantıların fiziksel yolunu bulmak için Unix komutunu kullanabilirsiniz .

Örnekler

Diyelim ki şu bağlantıya sahibim:

$ ls -l /usr/bin/etags
lrwxrwxrwx. 1 root root 29 Dec 10 22:56 /usr/bin/etags -> /etc/alternatives/emacs.etags

$ ls -l /etc/alternatives/emacs.etags
lrwxrwxrwx. 1 root root 20 Dec 10 22:56 /etc/alternatives/emacs.etags -> /usr/bin/etags.ctags

$ ls -l /usr/bin/etags.ctags
lrwxrwxrwx. 1 root root 5 Dec 10 22:56 /usr/bin/etags.ctags -> ctags

  1. Sembolik bir bağın işaret ettiği değeri bulmak için

    $ readlink /usr/bin/etags
    /etc/alternatives/emacs.etags

    NOT: Yukarıdaki sonuç başka bir bağlantı olabilir. Bu sorunu çözmek için aşağıdaki # 2'ye bakın.

  2. Değerin mutlak yolunu bulmak için sembolik bir bağ

    $ readlink -f /usr/bin/etags
    /usr/bin/ctags

0

Anlamıyorum - nasıl bir sarıcı bağlantı tamam, ama bir sarıcı komut dosyası değil inanıyoruz ? Her ikisi de sadece dolaylı düzeydir. Yine de kullanıcılarınıza yalnızca belirli bir dizinden aramalarını istemeniz gerekmez mi?

Her durumda, geçerli çalışma dizinini $PATHelbette alabilirsiniz:

 echo "echo \"Hi! I'm python\"" >|./python 
 chmod +x ./python 
 PATH="${PWD}:${PATH}" 
 python

 #OUTPUT#
 Hi! I'm python

 rm python 
 python -V 
 ln -s /usr/bin/python2 ./python 
 python -V

 #OUTPUT#
 Python 3.4.0
 Python 2.7.6

 PATH="${PATH#"${PWD}:"}" 
 python -V

 #OUTPUT#
 Python 3.4.0

Lütfen alın. senin dışında $PATH. Bu korkunç bir fikir.


.$ PATH'ımda neden kötü bir fikir var? Sonuna koyarsam, bakılacak son yer geçerli çalışma dizinimdir (yani `` PATH = "$ {PATH}: $ {PWD}"). Bir sarıcı komut dosyası , her python dosyası için ek bir dosya oluşturmak zorunda Python çalıştırılabilir bir sarmalayıcı bağlantı sadece benim için bir şey yaratır
Avery Chan

@AveryChan sanmıyorum. Bir sarıcı komut dosyası, yürütülebilir işlevle aynı ada sahip bir kabuk işlevini veya diğer adını kaynaklayabilir. Ayrıca --bind mountgeçerli dizinde çalıştırılabilir veya (hatta linux, sanırım) chrootgerektiği gibi bile olabilir . Fakat . içinde $PATHiçin işler hiç ve dizinde özgü değildir. Bu kullanıcılarınız için tehlikelidir. Her durumda, yukarıda nasıl yapılacağını çok net bir şekilde gösterdim. İhtiyaçlarınızı karşılamıyor mu?
mikeserv

0

Yeniden @ cevap, içindeki python sürümü /usr/bingerçek bir python değil.

Bu üç şekilde açıkça görülmelidir:

  1. Aldığımız hata genellikle python'un ürettiği hata değildir. Python'un davranışı başka bir python aramak değil, python komut dosyalarını yürütmektir.

  2. Çalıştırılan shasum /usr/bin/pythonve aslında python2.7'yi hesaplarsanız :

shasum /usr/bin/python
3782d9ab14b35037c9c7fb665439a5fa695c54a6  /usr/bin/python
shasum /usr/bin/python2.7
476fa96c80ac26a85b2d3b01ddfd19e513660c2c  /usr/bin/python2.7

Tamamen farklılar. Ayrıca, dosya boyutları ~ 20 bin bayt olarak değişir:

ll /usr/bin/python
-rwxr-xr-x  1 root  wheel  66880 May 17  2019 /usr/bin/python

vs.

ll /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
-rwxr-xr-x  1 root  wheel  43104 May 17  2019 /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
  1. Son olarak, python2.7 ve python'u kodalayabilir ve sembolleri araştırabilirsiniz. Bu sadece 'osx üzerinde python2.7 python2 symlink nasıl' kapsamı dışında biraz.

Yani (hatanın gösterdiği gibi) /usr/bin/pythondöner ve arar /usr/bin/python2.7:

ll /usr/bin/python2.7
lrwxr-xr-x  1 root  wheel  75 Jul  1  2019 /usr/bin/python2.7 -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7

Bu yüzden aşağıdaki işler (nezaket @ liangmin-li'nin cevabı):

    ln -s /System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 /usr/local/bin/python2

Siteye hoş geldiniz. Örnek lsçıktınızdan /usr/bin/python"gerçek bir python değil" nasıl göreceğinize ilişkin bazı açıklamalar eklemek isteyebilirsiniz .
AdminBee

Biraz açık bir şekilde ortada ama bunu nasıl belirleyebileceğimizi güncelleyebilirim.
smaudet

Tipik bir pythontercüman ikili boyutunu bilen biri için olabilir , ancak buradaki cevapların daha genel bir U&L kitlesi için kullanılabilir olması gerektiğini unutmayın ...
AdminBee

1
Numunemi güncelledim. İkili kimliğin kanıtlanması zor bir sorundur, bu yüzden burada tam olarak ele almıyorum (boyutlar arasında yasal olarak farklı olabilir, davranışlar değişebilir - güncellenmiş cevabımda yayınladığım kanıt, bu sistemin nasıl davrandığına göre bir vanilya python kurulum davranması gerekiyordu.Python ikili ters mühendislik hakkında bir cevap burada uygun veya gerçekten yararlı olacağını sanmıyorum). Ama ne demek istediğini anladım.
smaudet
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.