Jak sprawdzić, czy program istnieje ze skryptu Bash?

Jak sprawdzić, czy program istnieje, w sposób, który zwróci błąd i zakończy działanie, lub będzie kontynuował działanie skryptu?

Wydaje się, że powinno być łatwo, ale mnie to dręczy.

 1637

30 answers

Odpowiedź

Zgodny z POSIX:

command -v <the_command>

Dla bash specyficznych środowisk:

hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords

Wyjaśnienie

Unikaj which. Nie tylko jest to zewnętrzny proces, który uruchamiasz, aby zrobić bardzo mało (co oznacza, że zbudowany jest jak hash, type lub command są znacznie tańsze), można również polegać na wbudowanych, aby rzeczywiście zrobić to, co chcesz, podczas gdy efekty zewnętrznych poleceń mogą się łatwo różnić w zależności od systemu.

Dlaczego to obchodzi?

  • wiele działających systemy mają which, który nawet nie ustawia statusu zakończenia , co oznacza, że if which foonawet tam nie będzie działać i zawsze zgłosi, że foo istnieje, nawet jeśli tak nie jest (zauważ, że niektóre powłoki POSIX wydają się to robić również dla hash).
  • wiele systemów operacyjnych sprawia, że which robi niestandardowe i złe rzeczy, takie jak zmiana wyjścia lub nawet hook do menedżera pakietów.

Więc nie używaj which. Zamiast tego użyj jednego z nich:

$ command -v foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ type foo >/dev/null 2>&1 || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }
$ hash foo 2>/dev/null || { echo >&2 "I require foo but it's not installed.  Aborting."; exit 1; }

(Minor side-note: some will sugerować 2>&- to to samo 2>/dev/null ale krótsze – to jest nieprawdziwe . 2>&- zamyka FD 2, co powoduje błąd w programie, gdy próbuje zapisać na stderr, co bardzo różni się od pomyślnego zapisu do niego i odrzucenia wyjścia (i jest niebezpieczne!))

Jeśli twój hash bang to /bin/sh, powinieneś dbać o to, co mówi POSIX. Kod wyjścia type i hash nie są zbyt dobrze zdefiniowane przez POSIX, a hash Kończy się pomyślnie, gdy polecenie nie exist (haven ' t seen this with type yet). Status wyjścia command jest dobrze zdefiniowany przez POSIX, więc jest prawdopodobnie najbezpieczniejszy w użyciu.

Jeśli twój skrypt używa bash, reguły POSIX nie mają już znaczenia i zarówno type, jak i hash stają się całkowicie bezpieczne w użyciu. {[7] } teraz ma -P do wyszukiwania tylko PATH i hash ma efekt uboczny, że lokalizacja polecenia zostanie zahaszowana( dla szybszego wyszukiwania następnym razem), co jest zwykle dobrą rzeczą, ponieważ prawdopodobnie sprawdzasz jego istnienia, aby faktycznie z niego korzystać.

Jako prosty przykład, oto funkcja, która działa gdate jeśli istnieje, w przeciwnym razie date:

gnudate() {
    if hash gdate 2>/dev/null; then
        gdate "$@"
    else
        date "$@"
    fi
}
 2349
Author: lhunath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-26 23:02:09

Poniżej znajduje się przenośny sposób sprawdzenia, czy polecenie istnieje w $PATH i {[7] } jest wykonywalne:

[ -x "$(command -v foo)" ]

Przykład:

if ! [ -x "$(command -v git)" ]; then
  echo 'Error: git is not installed.' >&2
  exit 1
fi

Sprawdzenie wykonywalności jest potrzebne, ponieważ bash zwraca plik nie wykonywalny, jeśli w $PATH nie znaleziono pliku wykonywalnego o tej nazwie.

Zauważ również, że jeśli plik nie wykonywalny o tej samej nazwie co plik wykonywalny istnieje wcześniej w $PATH, dash zwraca pierwszy plik, nawet jeśli drugi zostanie wykonany. To jest błąd i jest w naruszenie standardu POSIX. [Zgłoś błąd] [Standard ]

Ponadto nie powiedzie się, jeśli szukana komenda została zdefiniowana jako alias.

 268
Author: nyuszika7h,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 14:18:46

Zgadzam się z lhunathem, aby zniechęcić do używania which, a jego rozwiązanie jest w pełni poprawne dla użytkowników Basha . Jednakże, aby być bardziej przenośnym, command -v stosuje się zamiast tego:

$ command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed.  Aborting." >&2; exit 1; }

Polecenie command jest zgodne ze standardem POSIX, zobacz jego specyfikację tutaj: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html

Uwaga: type jest zgodny z POSIX, ale type -P nie jest.

 193
Author: GregV,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-23 20:31:46

Mam funkcję zdefiniowaną w moim .bashrc to ułatwia.

command_exists () {
    type "$1" &> /dev/null ;
}

Oto przykład jak to jest używane (z mojego .bash_profile.)

if command_exists mvim ; then
    export VISUAL="mvim --nofork"
fi
 82
Author: Josh Strater,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-14 09:24:40

Zależy od tego, czy chcesz wiedzieć, czy istnieje w jednym z katalogów w zmiennej $PATH, czy też znasz jej absolutną lokalizację. Jeśli chcesz wiedzieć, czy jest w zmiennej $PATH, Użyj

if which programname >/dev/null; then
    echo exists
else
    echo does not exist
fi

W przeciwnym razie użyj

if [ -x /path/to/programname ]; then
    echo exists
else
    echo does not exist
fi

Przekierowanie do /dev/null/ w pierwszym przykładzie blokuje wyjście programu which.

 67
Author: dreamlax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 22:01:52

Rozszerzając odpowiedzi @lhunath i @ GregV, oto kod dla osób, które chcą łatwo umieścić ten czek wewnątrzif:

exists()
{
  command -v "$1" >/dev/null 2>&1
}

Oto jak go używać:

if exists bash; then
  echo 'Bash exists!'
else
  echo 'Your system does not have Bash'
fi
 29
Author: Romário,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 20:42:45

Spróbuj użyć:

test -x filename

Lub

[ -x filename ]

Ze strony podręcznika bash Pod wyrażenia warunkowe :

 -x file
          True if file exists and is executable.
 20
Author: dmckee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-26 11:19:09

Aby użyć hash, Jak @lhunath sugeruje , w skrypcie bash:

hash foo &> /dev/null
if [ $? -eq 1 ]; then
    echo >&2 "foo not found."
fi

Ten skrypt uruchamia hash, a następnie sprawdza, czy kod zakończenia najnowszego polecenia, wartość zapisana w $?, jest równa 1. Jeśli hash nie znajdzie foo, kodem wyjścia będzie 1. Jeśli foo jest obecny, kod wyjścia to 0.

&> /dev/null przekierowuje standardowy błąd i standardowe wyjście z hash tak, że nie pojawia się na ekranie i echo >&2 zapisuje wiadomość do standard błąd.

 16
Author: dcharles,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:11

Nigdy nie udało mi się uruchomić powyższych rozwiązań na pudełku, do którego mam dostęp. Po pierwsze, typ został zainstalowany (robi to, co więcej robi). Potrzebna jest więc dyrektywa wbudowana. To polecenie działa dla mnie:

if [ `builtin type -p vim` ]; then echo "TRUE"; else echo "FALSE"; fi
 9
Author: Magnus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 06:27:47

Jeśli sprawdzisz istnienie programu, prawdopodobnie i tak go uruchomisz później. Dlaczego nie spróbować uruchomić go w pierwszej kolejności?

if foo --version >/dev/null 2>&1; then
    echo Found
else
    echo Not found
fi

Jest to bardziej wiarygodne sprawdzenie, czy program działa, niż Przeglądanie katalogów ścieżek i uprawnień do plików.

Dodatkowo możesz uzyskać przydatne wyniki z twojego programu, takie jak jego wersja.

Oczywiście wadą jest to, że niektóre programy mogą być ciężkie do uruchomienia, a niektóre nie mają --version opcji natychmiastowego (i pomyślnie) wyjść.

 7
Author: 0xF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 15:14:30

Dlaczego nie używać Bash builtins, jeśli możesz?

which programname

...

type -P programname
 6
Author: Steven Penny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 06:28:09

Sprawdź wiele zależności i poinformuj użytkowników końcowych o statusie

for cmd in "latex" "pandoc"; do
  printf "%-10s" "$cmd"
  if hash "$cmd" 2>/dev/null; then printf "OK\n"; else printf "missing\n"; fi
done

Przykładowe wyjście:

latex     OK
pandoc    missing

Dostosuj 10 do maksymalnej długości polecenia. Nie Automatyczny, bo nie widzę sposobu, w jaki POSIX to robi: Jak wyrównać kolumny oddzielonej spacjami tabeli w Bash?

 5
Author: Ciro Santilli 新疆改造中心 六四事件 法轮功,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 07:29:02

Dla zainteresowanych, żadna z powyższych metod nie działa, jeśli chcesz wykryć zainstalowaną bibliotekę. Domyślam się, że możesz albo fizycznie sprawdzić ścieżkę (potencjalnie dla plików nagłówkowych itp.), Albo coś w tym stylu (jeśli jesteś na dystrybucji opartej na Debianie):

dpkg --status libdb-dev | grep -q not-installed

if [ $? -eq 0 ]; then
    apt-get install libdb-dev
fi

Jak widać z powyższego, odpowiedź "0" z zapytania oznacza, że pakiet nie jest zainstalowany. Jest to funkcja "grep" - "0" oznacza, że znaleziono dopasowanie, " 1 " oznacza, że nie znaleziono dopasowania.

 4
Author: Nathan Crause,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-15 23:16:17

hash foo 2>/dev/null: współpracuje z zsh, bash, dash i ash.

type -p foo: wygląda na to, że działa z zsh, bash i ash (busybox), ale nie dash (interpretuje -p jako argument).

command -v foo: działa z zsh, bash, dash, ale nie ash (busybox) (-ash: command: not found).

Należy również pamiętać, że builtin nie jest dostępny z ash i dash.

 4
Author: blueyed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-21 00:18:23

Polecenie which może być przydatne. człowiek, który

Zwraca 0, jeśli plik wykonywalny został znaleziony, 1, jeśli nie został znaleziony lub nie jest wykonywalny:

NAME

       which - locate a command

SYNOPSIS

       which [-a] filename ...

DESCRIPTION

       which returns the pathnames of the files which would be executed in the
       current environment, had its arguments been  given  as  commands  in  a
       strictly  POSIX-conformant  shell.   It does this by searching the PATH
       for executable files matching the names of the arguments.

OPTIONS

       -a     print all matching pathnames of each argument

EXIT STATUS

       0      if all specified commands are found and executable

       1      if one or more specified commands is  nonexistent  or  not  exe-
          cutable

       2      if an invalid option is specified

Fajne jest to, że sprawdza czy plik wykonywalny jest dostępny w środowisku, w którym jest uruchamiany - zapisuje kilka problemów...

- Adam

 3
Author: Adam Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-26 21:56:53

Powiedziałbym, że nie ma przenośnego i 100% niezawodnego sposobu ze względu na wiszące aliases. Na przykład:

alias john='ls --color'
alias paul='george -F'
alias george='ls -h'
alias ringo=/

Oczywiście tylko ten ostatni jest problematyczny (bez urazy dla Ringo!) Ale wszystkie z nich są ważne alias es z punktu widzenia command -v.

Aby odrzucić zwisające takie jak ringo, musimy przeanalizować wyjście wbudowanego w powłokę polecenia alias i wprowadzić do nich rekurencję (command -v nie jest tutaj lepsza od alias.) Nie ma dla niego przenośnego rozwiązania, a nawet specyficznego dla Basha rozwiązanie jest dość żmudne.

Zauważ, że takie rozwiązanie bezwarunkowo odrzuci alias ls='ls -F'

test() { command -v $1 | grep -qv alias }
 3
Author: nodakai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-10 02:31:54

Jeśli nie ma dostępnej zewnętrznej komendy type (jako oczywiste tutaj), możemy użyć zgodnego z POSIX env -i sh -c 'type cmd 1>/dev/null 2>&1':

# portable version of Bash's type -P cmd (without output on stdout)
typep() {
   command -p env -i PATH="$PATH" sh -c '
      export LC_ALL=C LANG=C
      cmd="$1" 
      cmd="`type "$cmd" 2>/dev/null || { echo "error: command $cmd not found; exiting ..." 1>&2; exit 1; }`"
      [ $? != 0 ] && exit 1
      case "$cmd" in
        *\ /*) exit 0;;
            *) printf "%s\n" "error: $cmd" 1>&2; exit 1;;
      esac
   ' _ "$1" || exit 1
}

# get your standard $PATH value
#PATH="$(command -p getconf PATH)"
typep ls
typep builtin
typep ls-temp

Przynajmniej na Mac OS X 10.6.8 używanie Bash 4.2.24 (2) command -v ls nie pasuje do przeniesionego /bin/ls-temp.

 2
Author: freno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:11

Do naśladowania Basha type -P cmd Możemy użyć zgodnego ze standardem POSIX env -i type cmd 1>/dev/null 2>&1.

man env
# "The option '-i' causes env to completely ignore the environment it inherits."
# In other words, there are no aliases or functions to be looked up by the type command.

ls() { echo 'Hello, world!'; }

ls
type ls
env -i type ls

cmd=ls
cmd=lsx
env -i type $cmd 1>/dev/null 2>&1 || { echo "$cmd not found"; exit 1; }
 1
Author: tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-01 17:49:22

Wariant skrótu ma jedną pułapkę: w wierszu poleceń można na przykład wpisać

one_folder/process

Aby proces został wykonany. W tym celu folder nadrzędny one_folder musi znajdować się w $PATH. Ale kiedy spróbujesz zahaszować to polecenie, zawsze się powiedzie:

hash one_folder/process; echo $? # will always output '0'
 1
Author: anycast.cw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-14 12:41:26

Popieram użycie "command-v". Np. tak:

md=$(command -v mkdirhier) ; alias md=${md:=mkdir}  # bash

emacs="$(command -v emacs) -nw" || emacs=nano
alias e=$emacs
[[ -z $(command -v jed) ]] && alias jed=$emacs
 1
Author: user2961933,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-06 19:06:48

Moja konfiguracja serwera Debiana. miałem problem, gdy wiele pakietów zawiera tę samą nazwę. na przykład apache2. więc to było moje rozwiązanie.

function _apt_install() {
    apt-get install -y $1 > /dev/null
}

function _apt_install_norecommends() {
    apt-get install -y --no-install-recommends $1 > /dev/null
}
function _apt_available() {
    if [ `apt-cache search $1 | grep -o "$1" | uniq | wc -l` = "1" ]; then
        echo "Package is available : $1"
        PACKAGE_INSTALL="1"
    else
        echo "Package $1 is NOT available for install"
        echo  "We can not continue without this package..."
        echo  "Exitting now.."
        exit 0
    fi
}
function _package_install {
    _apt_available $1
    if [ "${PACKAGE_INSTALL}" = "1" ]; then
        if [ "$(dpkg-query -l $1 | tail -n1 | cut -c1-2)" = "ii" ]; then
             echo  "package is already_installed: $1"
        else
            echo  "installing package : $1, please wait.."
            _apt_install $1
            sleep 0.5
        fi
    fi
}

function _package_install_no_recommends {
    _apt_available $1
    if [ "${PACKAGE_INSTALL}" = "1" ]; then
        if [ "$(dpkg-query -l $1 | tail -n1 | cut -c1-2)" = "ii" ]; then
             echo  "package is already_installed: $1"
        else
            echo  "installing package : $1, please wait.."
            _apt_install_norecommends $1
            sleep 0.5
        fi
    fi
}
 1
Author: ThCTLo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-27 14:26:27

Jeśli nie możecie uruchomić rzeczy powyżej/poniżej i wyciągnąć włosów z pleców, spróbujcie uruchomić tę samą komendę za pomocą bash -c. Po prostu spójrz na to somnambular delirium, tak naprawdę dzieje się, gdy uruchamiasz $(sub-command): {]}

Pierwszy. Może dać zupełnie inną wydajność.

$ command -v ls
alias ls='ls --color=auto'
$ bash -c "command -v ls"
/bin/ls
Druga. Może w ogóle nie dawać żadnych wyników.
$ command -v nvm
nvm
$ bash -c "command -v nvm"
$ bash -c "nvm --help"
bash: nvm: command not found
 1
Author: user619271,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-26 09:23:12

Jeśli chcesz sprawdzić, czy program istnieje i jest naprawdę programem, a nie wbudowanym poleceniem bash , to command, type i hash nie są odpowiednie do testowania, ponieważ wszystkie zwracają 0 status zakończenia dla wbudowanych poleceń.

Na przykład istnieje program time , który oferuje więcej funkcji niż wbudowane polecenie time. Aby sprawdzić, czy program istnieje, proponuję użyć which jak w poniższym przykładzie:

# first check if the time program exists
timeProg=`which time`
if [ "$timeProg" = "" ]
then
  echo "The time program does not exist on this system."
  exit 1
fi

# invoke the time program
$timeProg --quiet -o result.txt -f "%S %U + p" du -sk ~
echo "Total CPU time: `dc -f result.txt` seconds"
rm result.txt
 1
Author: rpr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-18 23:19:53

Jest tu mnóstwo opcji, ale byłem zaskoczony, że nie ma szybkich jednolinijkowych, tego używałem na początku moich skryptów: [[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1>&2 ; exit 1; } [[ "$(command -v java)" ]] || { echo "java is not installed" 1>&2 ; exit 1; }

Jest to oparte na wybranej tutaj odpowiedzi i innym źródle(a ja trochę się bawię).

Mam nadzieję, że będzie to przydatne dla innych.
 1
Author: keisar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 12:02:30
checkexists() {
    while [ -n "$1" ]; do
        [ -n "$(which "$1")" ] || echo "$1": command not found
        shift
    done
}
 0
Author: Anonymous,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-18 07:54:44

Używam tego, ponieważ jest to bardzo proste:

if [ `LANG=C type example 2>/dev/null|wc -l` = 1 ];then echo exists;else echo "not exists";fi

Lub

if [ `LANG=C type example 2>/dev/null|wc -l` = 1 ];then
echo exists
else echo "not exists"
fi

Używa wbudowanej powłoki i programu echo status do stdout i nic do stderr z drugiej strony, jeśli polecenie nie zostanie znalezione, wyświetla status ECHA tylko do stderr.

 0
Author: A.N,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-22 00:48:43

Skrypt

#!/bin/bash

# Commands found in the hash table are checked for existence before being
# executed and non-existence forces a normal PATH search.
shopt -s checkhash

function exists() {
 local mycomm=$1; shift || return 1

 hash $mycomm 2>/dev/null || \
 printf "\xe2\x9c\x98 [ABRT]: $mycomm: command does not exist\n"; return 1;
}
readonly -f exists

exists notacmd
exists bash
hash
bash -c 'printf "Fin.\n"'

Wynik

✘ [ABRT]: notacmd: command does not exist
hits    command
   0    /usr/bin/bash
Fin.
 0
Author: ecwpz91,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-06 00:42:27

Command-v działa poprawnie, jeśli opcja POSIX_BUILTINS jest ustawiona dla <command> do testowania, ale może się nie udać, jeśli nie. (działa u mnie od lat, ale ostatnio natrafiłem na taki, w którym nie działa).

Uważam, że następujące elementy są bardziej odporne na awarie:

test -x $(which <command>)

Ponieważ testuje 3 rzeczy: ścieżkę, wykonanie i pozwolenie.

 0
Author: AnthonyC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-25 16:53:46

Używam bardzo poręcznej i krótkiej wersji:

dpkg -s curl 2>/dev/null >/dev/null || apt-get -y install curl

Tak proste, jeśli trzeba sprawdzić tylko JEDEN program.

 0
Author: Xynox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 12:29:48

Świetna odpowiedź i Wyjaśnienie przez @lhunath. Uratowałeś mi dzień. Wydłużyłam trochę. Nie mogłem się kontrolować dzieląc się tym-mając nadzieję, że może to być przydatne dla kogoś. Jeśli ktoś musi sprawdzić (tablicę) wiele programów, oto szybki fragment.

Co on robi? (1) odczyt tablicy programów. (2) Pokaż wiadomość dla nieudany program. (3) Poproś użytkownika o kontynuowanie (wymuszanie pętli) opcji y / n do walidacji pozostałych programów.
#!/bin/bash

proginstalldir=/full/dir/path/of/installation
progsbindir=$proginstalldir/bin
echo -e "\nMy install directory - $proginstalldir"
echo -e "My binaries directory - $progsbindir"

VerifyInstall () {
clear
myprogs=( program1 program2 program3 program4 program5 programn ); 
echo -e "\nValidation of my programs started...."
for ((i=0; i<${#myprogs[@]}; i++)) ; do 
command -v $progsbindir/${myprogs[i]} >/dev/null && echo -e "Validating....\t${myprogs[i]}\tSUCCESSFUL"  || { echo -e "Validating.... \t${myprogs[i]}\tFAILED" >&2;
while true; do 
printf "%s:  "  "ERROR.... Validation FAILED for ${myprogs[i]} !!!! Continue?"; read yn; 
case $yn in [Yy] )  echo -e "Please wait..." ; break;;
[Nn]) echo -e "\n\n#################################\n##   Validation Failed .. !!   ##\n#################################\n\n" ; exit 1; break;;
*) echo -e "\nPlease answer y or n then press Enter\n"; esac; done; >&2; }; done
sleep 2
}

VerifyInstall
 0
Author: Ajay Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-25 16:58:06