shは$ PATHを考慮しません。

shは$ PATHを考慮しません。

これは効果があります

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(仕様の基礎となるサブセット)、そうするのでこれを必要とせず、最近の実装ではこれを要求しません(または)。これは望ましくありません。$PATHsh filefilekshshshmksh

実際、POSIXではこれを許可し、一部の実装では逆の問題が発生します。

sh -- "$file"

POSIXはパスが保存されているファイルの解釈を保証しないため、$file次のことを行う必要があります。

case $file in
  ('') echo >&2 error;;
  (*/*) sh -- "$file";;
  (*) sh "./$file";;
esac

ポータブルで解決してみてください。

これが人々が以下を使うのを見る理由でもあります。

sh ./file

file現在のディレクトリで解釈されていることを確認し、現在の作業ディレクトリではなく現在の作業ディレクトリからコマンドを実行するなど、欠落している場合は、完全に関連していない一部のスクリプトを解釈するリスクを負うことを望ま$PATHない場合。file./lsls$PATH

このユーティリティには含まれていない.同様の$PATH問題があります。 POSIX は、sh モードではない場合、bash または zsh でファイルを検索することはできませんが、現在のディレクトリのファイルを解釈するフォールバックは許可しません。 'に該当する:検索しません。で検索に戻ります。では動作が似ています。$file/$PATHcsh.source$PATHzshsource$PATHbashsource.

ここでスクリプトが にあり、$PATH実行権限があると仮定すると、次のように簡単に入力できます。

gap.sh

gap.shで見つけるために$PATH。スクリプトにshebangがない場合は、shPOSIX準拠のインタープリタとして解釈する必要があります。

読み取り権限があるが実行権限がない場合は、次のことができます。

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 - fileksh~/bin/file/tmp/file

答え2

PATHこの例では、実行中のプログラムを考慮しますsh

/bin:/opt/gap-4.11.1/binあなたの場合と同様に、PATH「直接」実行できる必要があります。以下を実行します。

gap.sh

実行権限がある限り。

関連情報