アプリケーションが$ PATHに存在するかどうかをテストするにはどうすればよいですか?


19

私は、可能な限りsh多くのDRYと多くの「すべての* nixで動作する」で動作するように、すべてのstartup / envスクリプトを記述しようとしています。これは、そこにないコードを実行しようとすると、コードが正常に失敗することを確認することを意味します。そのためには、プログラムが存在するかどうかをテストできる必要があります。ファイルが存在するかどうかをテストする方法は知っていますが、アプリケーションがパス内で実行可能であるかどうかをテストする方法はわかりません。これらの一部はarch、ubuntu、およびcentosで動作する必要があるため、$ PATHを使用します。rootを持たないシステムのhomedirにインストールされるものもあれば、インストールされないものもあれば、システムパスにインストールされるものもあります。


2
このSOの答えは、そのような質問のためにブックマークしたものです。
jw013

回答:


19

を使用しtype commandnameます。commandnameエイリアス、関数、組み込みコマンドまたは外部コマンド(で検索$PATH)が実行可能であれば、これはtrueを返します。または、組み込みコマンドまたは外部コマンド(で検索)のcommand commandname場合にtrueを返すuse を使用します。commandname$PATH

exists () {
  type "$1" >/dev/null 2>/dev/null
}

常に0を返す、または返さないshバリアントがいくつかあります(POSIXより前/bin/sh、OSF1≤3.x の下、およびNetBSDの初期バージョンといくつかの20世紀のLinuxディストリビューションにあるAlmquistシェルのバージョンを知ってtypeいます)。存在します。これらのミレニアムとともに出荷されたシステムはないと思います。それらに遭遇した場合、$PATH手動で検索するために使用できる機能は次のとおりです。

exists () { (
    IFS=:
    for d in $PATH; do
      if test -x "$d/$1"; then return 0; fi
    done
    return 1
) }

この関数は、組み込み関数および関数を除外して、で名前を検索する場合に一般的に役立ちます$PATH。ほとんどのシェルにはこれが組み込まれていますが、command -vPOSIXへの比較的最近の追加機能です(POSIX:2004ではオプションです)。これは基本的にプログラマ向けのバージョンですtype。実行可能ファイルのフルパス$PATH、組み込み関数または関数の裸の名前、およびエイリアスのエイリアス定義を出力します。

exists_in_path () {
  case $(command -v -- "$1") in
    /*) return 0;;
    alias\ *) return 1;; # alias
    *) return 1;; # built-in or function
  esac
}

Ksh、bash、およびzshも、type -pで実行可能ファイルのみを検索する必要があります$PATH。bashでは、組み込みまたは関数のtype -p foo場合の戻りステータスは0ですfoo。で実行可能ファイルをテスト$PATHする場合は、出力が空でないことを確認する必要があります。type -pPOSIXにはありません。たとえば、Debianの灰(/bin/shUbuntuにあります)にはありません。


@gilles、これ(または同様のもの)if [ type keychain ]; thenは機能しませんか?私はエラーを取得/home/xenoterracide/.zshrc:84: parse error: condition expected: type、私は関数を書くことができたとが存在する...私は、これは意味が簡単かもしれないと思った...
xenoterracide

@xenoterracide:括弧を削除してください!
ジル 'SO-悪であるのをやめる'

私は、あなたが探していると思うif type $APP >/dev/null 2>/dev/null; then ...あなたたくありません[]
スティーブンD

4
バ、私はリフレッシュする必要があることを知っていました。再びジルにBeatられた!
スティーブンD

type -p$PATH(エイリアス、関数、またはビルトインではなく)で特にコマンドを探している場合。
一時的な

1

外部プログラムのみを探している場合は、どちらを使用することもできます。しかし、それがどれほど移植性があるのか​​わかりません。


3
理論的には、typeまたはよりも移植性が低くなりcommandます。whichたとえば、POSIXにはありません。実際にwhichは、ほとんどどこにでも存在しますが、一部の場所(cshスクリプトとして実装されている場所)では、別のパス(aが原因)を使用するため.cshrc、目的に反します。
ジル「SO-悪であるのをやめる」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.