シンボリックリンクを見つけるために「realpath」を取得するにはどうすればよいですか?


13

私はbashシェルとしてMacOSXを使用しています。このように作成されたシンボリックリンクがあります。

ln -s /usr/bin/python python2 

python2を使用するパッケージがあり、現在の作業ディレクトリに/usr/bin/python実際にpython2であるシンボルリンクを作成したい。python2コマンドラインからを実行すると、次のエラーが表示されます。

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

しかし、このように呼び出すと./python2、パスが正しく解決されます。私PATH.それを持っています。実際、テスト用に変更するだけ.で済みます。

どうすれば解決できますか?ありがとう!


環境

下記の提案された解決策の多くは私にはうまくいきません。私は、人々がテキストの海にdrれないように、できるだけ集中して簡潔に私の質問を蒸留しようとしましたが、明らかに、より多くの背景を提供する必要があります。

gitからクローンを作成したパッケージで開発しようとしています。元のパッケージはgit-multimail、Linuxの一部のバリアントで開発されました(Ubuntuを推測しています)。MacOSXで可能な限り変更を加えずに使用できるように変更しようとしています。提案されたソリューションのいくつかが理想的ではない理由はここにあります:

  1. ルートとしてpython2、/ usr / bin /にシンボリックリンクを作成します。私はこれを必要としないソリューションを探しています。これは最初は明らかなオプションでしたが、ホストシステムを可能な限り変更しないソリューションが必要です。これが、現在の作業ディレクトリに一時シンボリックリンクを作成し、CWD(つまり.)をパスに追加し、終了時にこれを破棄する(つまり、シンボリックリンク)理由でした。

  2. ラッパースクリプトを作成して、既存のPythonでPythonスクリプトを呼び出します。これに関する問題は、正しい実行環境を見つけるためにshebangに応じて、テストスイートの多くが実際のscript_filesを実行可能ファイルとして使用することです。これは、テストスイートをかなり編集することを意味します。このコンテキストでは(テストフレームワークのスニペットについては以下を参照)、すべての.pyファイルにラッパーを追加する必要があります。さらに、ユーザー/開発者は、使用しているシステムに応じてパッケージを使用するためのさまざまなルールを認識する必要があります(つまり、MacOSXでは、ラッパー経由で呼び出すか、明示的に呼び出すことなくpythonファイルを使用しないでください/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. すべてのpython2参照をに変更していますpythonREADMEはこれを提案しますが、システムは変更を新しいバージョンと見なし、実際には(意味的には)変更されていないため、バージョン管理を事実上無効にします。

私は(3)を使用していますが、より良い解決策を見つけようとしています。私はこれが単なる方法であることを受け入れるつもりです(つまり/usr/bin/python、テストスイートと実際のフレームワークに多くの変更を加えることなく、ポータブルで控えめな「python2」を指す適切な方法はありません)


1
おい!ジャストln -s /usr/bin/python /usr/bin/python2
enedil

実際、Linuxでgit-multimailを開発しています。しかし、パッチとテスターがOS Xで動作することを歓迎します。
マチューモイ

展開された質問には、依然として重要な詳細が欠けています。実行可能スクリプトのシェバン行はどのように見えますか?以下のためにgit-multimail.pyそれがある#!/usr/bin/env python2ので、これを行うには(比較的)簡単な方法があります。
アレクシス

@enedilのコメントは機能しませんでしたが、機能ln -s /usr/bin/python2.7 /usr/local/bin/python2しました
Phylliida

回答:


3

シンボリックリンクを解決(または調査)する必要がある場合は、プラットフォームに依存しないbashライブラリ「realpath-lib」を使用できます。デフォルトでは、readlinkをエミュレートし、MacまたはUnixで動作します。これは、上で見つけることができるのGithubのBitbucket、それは無料です。

ただし、ローカル(作業)ディレクトリから(./python2ではなく)python2を実行したいだけのようです。.bashrcのエイリアスを使用してこれを行うこともできます。そうしないと、PATH環境変数に作業ディレクトリ(シンボリックリンクを含む)を追加する必要があります。これは、現在のセッションに対してのみ、または将来のセッションのために.bashrcファイル内で行うこともできます。これは、特定のユーザーだけのソリューションになる可能性があります。

すべてのユーザーに有効な別のオプションは、パス上の別のディレクトリ、たとえば/ usr / local / binに/ usr / bin / pythonへのpython2シンボリックリンクを作成することです。おそらく次のようなもの:

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

次に、ユーザーまたはスクリプトはpythonまたはpython2コマンドを見つける必要があります。もちろん、このオプションをインストールするには、管理者(root)特権が必要です。


私は最終的にあきらめました。コード内で「python2」を想定している場所が多すぎるため、すべてのローカライズソリューションがすべての可能性をカバーしているわけではありません。これは、この爪に最も適したハンマーです。
エイブリーチャン

@Avery、私のソリューションを試しましたか?問題はありましたか?追加python2する必要はありませんでした/usr/bin(正直に言って、改善として追加することを考えていますが)。
アレクシス

エイリアス(...)でこれを行うことは可能であるかもしれないそれは別名影響としてのみ、コマンドラインではなくスクリプトことはできません。Debian 7.5でPythonのデフォルトバージョンを変更する方法を
ピョートルドブロゴスト14

15

同じプログラムの複数のバージョンを管理および切り替えるために、Appleのシステムを悪用していると思います。次の名前のスクリプトを使用すると、エレガントではありませんが問題なく、目的を達成できますpython2

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

それを実行可能にします(chmod +x python2)、あなたはビジネスにいます。

問題の説明:

あなたが実行すると/usr/bin/python、それは見つけて実行しpython2.7 、同じディレクトリに。シンボリックリンクは、システムがへのシンボリックリンクをたどり、そこを探して見つからない/usr/binために失敗します python2。シンボリックリンクの代わりに「ハードリンク」を使用すると、さらに一歩進むことができます。

rm python2
ln /usr/bin/python python2

シンボリックリンクはありません。同じファイル(inode)のファイル名は2つだけです。しかし、今私は次のメッセージで失敗します:

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

python22.7フレームワークが2.7作成した名前に追加されていることに注意してください!これを解明し、その期待に一致するリンクのフォレストをセットアップする代わりに、バージョン管理フレームワークの邪魔にならないようにして、上記のソリューションを使用することをお勧めします。

PS。より良い解決策があるかもしれません:そもそも何をする必要があるかを説明するなら(なぜpython2のエイリアスとして提供する必要があるのpythonか)、誰かがおそらくあなたを別の方法で助けることができるでしょう。これは、stackexchange言語の「XY問題」として知られています...


あなたが実行すると/usr/bin/python、それが見つかったと同じディレクトリにpython2.7を実行します。これは非常に紛らわしい声明です。あなた/usr/bin/pythonがシンボリックリンクである場合を説明する場合は、より具体的にしてください。
ピョートルドブロゴスト14

それは驚くほど悪いです
。-ニコラス

驚くほど悪いのは何ですか?
アレクシス

2

試してください:

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

なぜあなたが下票を得ているのかわからない、これが私のために働いた唯一の解決策である
-xApple

1

Unixコマンドreadlinkを使用して、リンクの物理パスを見つけることができます。

次のリンクがあるとします。

$ 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. シンボリックリンクが指す値を見つけるには

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

    注:上記の結果は別のリンクである可能性があります。これを解決するには、以下の#2を参照してください。

  2. シンボリックリンクが指す値の絶対パスを見つけるには

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

0

わかりません-ラッパーリンクは問題ないが、ラッパースクリプトは問題ないと思いますか?どちらも間接的なレベルです。また、特定のディレクトリからのみ呼び出すようにユーザーに指示する必要はありませんか?

いずれにしても、$PATHもちろん現在の作業ディレクトリを取得できます:

 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

取得してください。あなたの$PATH。それは恐ろしいアイデアです。


.$ PATHに悪い考えがあるのはなぜですか?最後に配置すると、最後に表示される場所は現在の作業ディレクトリ(つまり、 `PATH =" $ {PATH}:$ {PWD} "です。ラッパースクリプトは、すべてのpythonファイルに対して、追加のファイルを作成する必要があります。Python実行可能ファイルへのラッパーリンクは、私がやるべきことを1つ作成するだけです
Avery Chan 14

@AveryChanそうは思いません。ラッパースクリプトは、実行可能ファイルと同じ名前のシェル関数またはエイリアスを提供できます。また、必要に応じ--bind mountて、現在のディレクトリにある実行可能ファイル(またはLinuxのみ)とすることもできchrootます。だが 。任意のディレクトリで$PATH機能し特定ではありません。これはユーザーにとって危険です。いずれにせよ、上記の方法を非常に明確に示しました。要件を満たしていませんか?
mikeserv 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.