これは効果があります
sh /opt/gap-4.11.1/bin/gap.sh
これはうまくいきません
sh gap.sh
エラーメッセージを返します。
sh: 0: Can't open gap.sh
ただし、必要なディレクトリは$PATH
確認どおりに配置されます。echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/gap-4.11.1/bin
何が問題なの?
答え1
POSIXでは、sh
実装が現在の作業ディレクトリに見つからない場合に検索することができますがfile
(仕様の基礎となるサブセット)、そうするのでこれを必要とせず、最近の実装ではこれを要求しません(または)。これは望ましくありません。$PATH
sh file
file
ksh
sh
sh
mksh
実際、POSIXではこれを許可し、一部の実装では逆の問題が発生します。
sh -- "$file"
POSIXはパスが保存されているファイルの解釈を保証しないため、$file
次のことを行う必要があります。
case $file in
('') echo >&2 error;;
(*/*) sh -- "$file";;
(*) sh "./$file";;
esac
ポータブルで解決してみてください。
これが人々が以下を使うのを見る理由でもあります。
sh ./file
file
現在のディレクトリで解釈されていることを確認し、現在の作業ディレクトリではなく現在の作業ディレクトリからコマンドを実行するなど、欠落している場合は、完全に関連していない一部のスクリプトを解釈するリスクを負うことを望ま$PATH
ない場合。file
./ls
ls
$PATH
このユーティリティには含まれていない.
同様の$PATH
問題があります。 POSIX は、sh モードではない場合、bash または zsh でファイルを検索することはできませんが、現在のディレクトリのファイルを解釈するフォールバックは許可しません。 'に該当する:検索しません。で検索に戻ります。では動作が似ています。$file
/
$PATH
csh
.
source
$PATH
zsh
source
$PATH
bash
source
.
ここでスクリプトが にあり、$PATH
実行権限があると仮定すると、次のように簡単に入力できます。
gap.sh
gap.sh
で見つけるために$PATH
。スクリプトにshebangがない場合は、sh
POSIX準拠のインタープリタとして解釈する必要があります。
読み取り権限があるが実行権限がない場合は、次のことができます。
sh -c '. gap.sh' sh arguments for gap.sh
$PATH
上記のように照会が実行されます。
歴史的にonがksh file
最初に検索されksh
ました$PATH
。これは setuid スクリプトをサポートするシステムのセキュリティの脆弱性です。次のようにできます。
ln -s /path/to/some/setuid/ksh/script /tmp/file
echo sh > ~/bin/file
PATH=$PATH:~/bin
cd /tmp
exec("file", ...)
shebangでwhichを呼び出すと、setuidユーザーとして実行され、#! /bin/ksh -
代わりに解釈されるため、スクリプトがsetuidルートの場合はrootシェルを取得します。/bin/ksh - file
ksh
~/bin/file
/tmp/file
答え2
PATH
この例では、実行中のプログラムを考慮しますsh
。
/bin:/opt/gap-4.11.1/bin
あなたの場合と同様に、PATH
「直接」実行できる必要があります。以下を実行します。
gap.sh
実行権限がある限り。