「onewhich」という小さなスクリプトがあります。その目的は のように動作することですがwhich
、オプションとして指定された実行可能ファイルの最初のオカレンスのみを、パスに表示される順序で検出します。
たとえば、パスがで、との/opt/bin:/usr/bin:/bin
両方がある場合、コマンドは を返します。/opt/bin/runme
/usr/bin/runme
onewhich runme
/opt/bin/runme
ただし、 もある場合は/usr/bin/doit
、代わりにコマンドonewhich doit runme
が返さ/usr/bin/doit
れます。
アイデアは、パスをたどり、指定された各実行可能ファイルをチェックし、存在する場合はそれを表示して終了することです。
ここまでのスクリプトです。
#!/bin/sh
for what in "$@"; do
for loc in `echo "${PATH}" | awk -vRS=: 1`; do
if [ -f "${loc}/${what}" ]; then
echo "${loc}/${what}"
exit 0
fi
done
done
exit 1
問題は、特殊文字を含む PATH ディレクトリについて改善したいということです。StackOverflow に関する 2 番目のシェルの質問は、awk や sed などのツールでパスを解析することがいかに悪いかについて語っています。それについてのbash faq エントリさえあります。(但し書き: これには bash を使用していませんが、推奨事項は引き続き有効です。)
そこで、このようにパイプでパスを区切るようにスクリプトを書き直してみました」
#!/bin/sh
for what in "$@"; do
echo "${PATH}" | awk -vRS=: 1 | while read loc ; do
if [ -f "${loc}/${what}" ]; then
echo "${loc}/${what}"
exit 0
fi
done
done
exit 1
これが本当の利点をもたらすかどうかはわかりません$loc
が(まだ引用符の中にあるため)、何らかの理由で無視されているように見えるため、機能しません。exit 0
または...何か(おそらくパイプを終了するwhileループを含むサブシェル)を終了しますが、スクリプトは1
毎回の値で終了します。
${PATH}
特殊文字が混乱を招くリスクなしに、ディレクトリをステップスルーするより良い方法は何ですか?
あるいは、車輪の再発明ですか? 既存のシェルツールに組み込まれているこれを行う方法はありますか?
これは Linux と FreeBSD の両方で実行する必要があるため、bash ではなく Bourne で記述しています。
ありがとう。