Bir uygulamanın $ PATH içinde olup olmadığını nasıl test edebilirim?


19

Mümkün olduğunca DRY ve shçok çalışmak için tüm başlangıç ​​/ env komut dosyaları yazmaya çalışıyorum : "Ben klonlamak her * nix üzerinde çalışır", mümkün. Bu, orada olmayan bir kodu çalıştırmayı denediğimde, kodun zarif bir şekilde başarısız olduğundan emin olmak anlamına gelir. Bu amaçla programların olup olmadığını test edebilmem gerekiyor. Bir dosyanın olup olmadığını sınamak nasıl biliyorum, ama bir uygulama yol içinde yürütülebilir olup olmadığını görmek için sınamak nasıl emin değilim. Bunların bazıları kemer, ubuntu ve centos üzerinde çalışması gerektiğinden $ PATH kullanmayı tercih ederim. Bazıları homedirime, kökümün olmadığı sistemlere, diğerleri yüklenmemiş olabilir ve diğerleri henüz sistem yollarına yüklenebilir.


2
Bu SO yanıtı , bu tür sorulara yer işareti koyduğum cevaptır .
jw013

Yanıtlar:


19

Kullanın type commandname. commandnameYürütülebilir herhangi bir şey varsa bu true değerini döndürür : diğer ad, işlev, yerleşik veya harici komut (yukarıya bakıldığında $PATH). Alternatif olarak, yerleşik veya harici bir komutsa ( command commandnamedöndürülen) true değerini döndüren kullanın .commandname$PATH

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

Birkaç sh varyantı vardır (kesinlikle POSIX öncesi; /bin/shOSF1 ≤3.x altında ve erken NetBSD sürümlerinde ve birkaç 20. yüzyıl Linux dağıtımlarında bulunan Almquist kabuğunun bazı sürümlerini biliyorum ), typeher zaman 0 döndürür veya vermez var olmak. Bu binyıl ile birlikte gelen hiçbir sistemin olduğunu düşünmüyorum. Onlarla hiç karşılaşırsanız, $PATHmanuel olarak aramak için kullanabileceğiniz bir işlev şunlardır:

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

Bu işlev genellikle yerleşikleri ve işlevleri hariç tutmak ve içindeki adı aramak istiyorsanız kullanışlıdır $PATH. Çoğu mermi bunun için yerleşiktir command -v, ancak POSIX'e nispeten yeni bir eklentidir (POSIX: 2004'ten itibaren hala isteğe bağlıdır). Temelde programcı dostu bir sürümdür type: içinde çalıştırılabilir dosyanın tam yolunu $PATH, yerleşik veya işlev için çıplak adı ve takma ad için bir takma ad tanımını yazdırır .

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

Ksh, bash ve zsh da type -psadece çalıştırılabilir dosyaları aramak zorundadır $PATH. Bash'te, yerleşik veya işlevse dönüş durumunun type -p foo0 olduğunu unutmayın foo; içinde bir yürütülebilir dosyayı test etmek istiyorsanız $PATH, çıktının boş olup olmadığını kontrol etmeniz gerekir. type -pPOSIX'te değil; örneğin Debian'ın ( /bin/shUbuntu'da bulunan) külünde yoktur.


@gilles, bu (veya benzer bir şey) if [ type keychain ]; thenişe yaramayacak mı? Ben hata var /home/xenoterracide/.zshrc:84: parse error: condition expected: typesanırım fonksiyon var yazmak olabilir ... Ben sadece bu bir anlamda daha basit olabileceğini düşündüm ...
xenoterracide

@xenoterracide: Köşeli parantezleri bırakın!
Gilles 'SO- kötü olmayı bırak'

Ben sizin için aradığınız düşünüyorum if type $APP >/dev/null 2>/dev/null; then ...Sen istemiyoruz [].
Steven D

4
Bah, tazelenmem gerektiğini biliyordum. Gilles tarafından tekrar dövüldü!
Steven D

type -pözellikle bir komut arıyorsanız $PATH(takma adlar veya işlevler veya yerleşikler değil).
ephemient

1

Yalnızca harici programlar arıyorsanız, hangisini kullanabilirsiniz. Ne kadar taşınabilir olduğunu bilmiyorum.


3
Teorik olarak, typeya da daha az taşınabilir command; whichörneğin POSIX'te değil. Uygulamada, whichhemen hemen her yerde var olmakla birlikte, bazı yerlerde (csh betiği olarak uygulandığı .cshrc), amacı yenen farklı bir yol (a nedeniyle) kullanır .
Gilles 'SO- kötü olmayı bırak'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.