実行ファイルへのシンボリックリンクを作成しました
ln -s /usr/bin/mydir/myexec /usr/bin/myexec
Bash で実行するとmyexec
、元のディレクトリにある適切なファイルが読み込まれませんmyexec
。
なぜこのようなことが起こるのでしょうか? また、どうすれば解決できるのでしょうか? 私は Fedora 15 x64 を使用しています。
答え1
相対パスで呼び出されるファイルは、/usr/bin/mydir/myexec
スクリプトが実行される現在の作業ディレクトリを基準にして検索されます。おそらく、スクリプトは現在、/usr/bin/mydir
その時点で実行された場合にのみ機能します。
これを解決する1つの方法は、インクルードされたファイルへの絶対パスを与えることです(ただし、必要なファイルが移動された場合はスクリプトを更新する必要があります)。または、次のreadlink
ようにして動的に絶対パスを計算する必要があります。
THISFILE=$(readlink -f -- "${0}")
THISDIR=${THISFILE%/*}
. "${THISDIR}/my_settings_file"
readlink -f
シンボリックリンクのターゲットを返します。- は
${THISFILE%/*}
、最後に/
削除された部分を含むシンボリックリンクのターゲット、つまり問題のファイルへのパスを返します。 ${THISDIR}
これでファイルへの絶対パスが含まれるようになり、3 行目のように使用できるようになります。
この質問はシェル スクリプトに関するものだと想定しました。他の言語では異なる方法があるかもしれません。
問題をほぼ完全に回避する別の方法は、パス内のバイナリをシンボリックリンクする代わりに、/usr/bin/myexec
次のような小さなスクリプトを作成することです。
#!/bin/sh
cd /usr/bin/mydir
./myexec
答え2
私は @daniel-anderson に同意しません。これらのソリューションは、呼び出されたプログラムへの引数を適切に考慮していないと思います。ほとんどすべての実行ファイルは、パス引数を現在のディレクトリからの相対パスとして扱うため、引数を渡しても機能しません。
プログラムが a から呼び出された場合に動作が変わる唯一のケースは、symlink
0 番目の引数を調べる場合です。シンボリック リンクを使用してこれを回避する方法は知りません。最も簡単な回避策は、次の形式で中間シェル スクリプトを作成することです。
#!/bin/sh
/path/to/executable/that/needs/0th/argument/to/be/actual/path $@
何らかの奇妙な理由で、実際には存在しない 0 番目の引数を指定する必要がある場合は、次のように exec -a を使用できます。
#!/bin/bash
(exec -a /path/to/executable/to/fool /path/to/fool/executable/with $@)
「-a」引数は厳密には POSIX 仕様ではない可能性があるので、特に bash を使用しました。パスに ~/bin フォルダーがあると仮定すると、最初の (通常の) ケースは次のように簡単に実行できます。
echo -e '#!/bin/sh\n/path/to/executable $@' > ~/bin/shortcut
chmod 755 ~/bin/shortcut
shortcut