Jak mogę 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.
30 answers
Odpowiedź
Zgodny z POSIX:
command -v <the_command>
Przykładowe użycie:
if ! command -v COMMAND &> /dev/null
then
echo "COMMAND could not be found"
exit
fi
Dla środowisk specyficznych dla Bash:
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 troska?
- wiele systemów operacyjnych ma
which
, który nawet nie ustawia statusu zakończenia , co oznacza, żeif which foo
nawet tam nie będzie działać i zawsze zgłosi, żefoo
istnieje, nawet jeśli tak nie jest (zauważ, że niektóre powłoki POSIX wydają się to robić również dlahash
). - 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 te:
$ 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-notatka: niektórzy sugerują, że 2>&-
jest tym samym 2>/dev/null
, ale krótszym – jest to nieprawda . 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
jest seen zakończy się pomyślnie, gdy polecenie nie istnieje(nie widziałem tego jeszcze z type
). 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. type
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 zazwyczaj jest to dobra rzecz, ponieważ prawdopodobnie sprawdzasz jego istnienie, 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
}
Alternatywa z kompletnym zestawem funkcji
Możesz użyć skryptów-common , aby zaspokoić swoje potrzeby.
Aby sprawdzić, czy coś jest zainstalowane, możesz zrobić:
checkBin <the_command> || errorMessage "This tool requires <the_command>. Install it please, and then run this tool again."
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
2020-07-01 07:05:49
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.
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 {[3] } jest zgodne z POSIX. Zobacz jego specyfikację tutaj: command-wykonaj proste polecenie
Uwaga: type
jest zgodny z POSIX, ale type -P
nie jest.
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
2020-01-16 03:25:42
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
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
To 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
.
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
2020-01-16 03:17:13
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
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.
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
2020-01-16 03:10:14
Aby użyć hash
, jak sugeruje @lhunath, w skrypcie Basha:
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
, aby nie pojawił się na ekranie i echo >&2
zapisuje wiadomość do standardowego błędu.
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
2020-01-16 03:30:20
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ść.
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
Nigdy nie dostałem poprzednich odpowiedzi do pracy nad pudełkiem, do którego mam dostęp. Po pierwsze, type
został zainstalowany (robiąc co more
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
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
2020-01-16 03:20:17
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
echo OK
else
echo missing
fi
done
Przykładowe wyjście:
latex OK
pandoc missing
Dostosuj 10
do maksymalnej długości polecenia. Nie jest to automatyczne, ponieważ nie widzę na to sposobu non-verbose POSIX:
Jak wyrównać kolumny oddzielonej spacjami tabeli w Bash?
Sprawdź, czy niektóre pakiety apt
są zainstalowane z dpkg -s
i zainstaluj je w przeciwnym razie .
Zobacz: sprawdź czy apt-get Pakiet jest zainstalowany, a następnie zainstaluj go, jeśli nie jest na Linuksie
Była wcześniej wspominana na: Jak mogę sprawdzić, czy program istnieje ze skryptu Bash?
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
2020-01-16 03:39:18
Jest tu mnóstwo opcji, ale byłem zaskoczony, że nie ma szybkich jednolinijkowych. To jest to, czego użył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.
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
2020-01-16 12:45:09
Polecenie -v
działa poprawnie, jeśli opcja POSIX_BUILTINS jest ustawiona dla <command>
do testowania, ale może się nie udać, jeśli nie. (To działa dla mnie od lat, ale ostatnio natknąłem się na jeden, gdzie nie działa.)
Uważam, że następujące są bardziej odporne na awarie:
test -x "$(which <command>)"
Ponieważ testuje trzy rzeczy: ścieżkę, istnienie i pozwolenie na wykonanie.
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
2020-12-17 20:51:48
hash foo 2>/dev/null
: współpracuje Z Z shell (Zsh), Bash, Dash i ash .
type -p foo
: wydaje się, że działa z powłoką z, Bash i ash (BusyBox ), ale nie Dash (interpretuje -p
jako argument).
command -v foo
: działa Z Z shell, Bash, Dash, ale nie z ash (BusyBox) (-ash: command: not found
).
Należy również pamiętać, że {[5] } nie jest dostępny z ash i Dash.
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
2020-01-16 03:44:13
Użyj Bash builtins, jeśli możesz:
which programname
...
type -P programname
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
2020-01-16 03:17:44
Dla zainteresowanych, żadna z metod w poprzednich odpowiedziach 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" - a " 0 "oznacza, że znaleziono dopasowanie, a" 1 " oznacza, że nie było dopasowania znaleziono.
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
2020-01-16 03:23:07
Powiedziałbym, że nie ma żadnego przenośnego i 100% niezawodnego sposobu ze względu na wiszące alias
es. 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 nadrzędna wobec alias
.) Nie ma na to żadnego przenośnego rozwiązania, a nawet Rozwiązanie specyficzne dla Bash jest dość żmudne.
Zauważ, że takie rozwiązanie bezwarunkowo odrzuci alias ls='ls -F'
:
test() { command -v $1 | grep -qv alias }
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
2020-01-16 12:39:43
To powie w zależności od lokalizacji, czy program istnieje, czy nie:
if [ -x /usr/bin/yum ]; then
echo "This is Centos"
fi
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
2020-04-07 12:55:28
Moja konfiguracja serwera Debian :
Miałem problem, gdy wiele pakietów zawierało 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
}
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
2020-01-16 03:50:53
Jeśli wy / dziewczyny nie możecie dostać rzeczy w odpowiedziach tutaj do pracy i wyrywają włosy z pleców, spróbuj uruchomić tę samą komendę za pomocą bash -c
. Spójrz na to somnambular delirium. Tak naprawdę dzieje się to po uruchomieniu $(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
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
2020-01-16 11:36:46
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
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
2020-01-16 12:42:15
Chciałem odpowiedzieć na to samo pytanie, ale uruchomić w pliku Makefile.
install:
@if [[ ! -x "$(shell command -v ghead)" ]]; then \
echo 'ghead does not exist. Please install it.'; \
exit -1; \
fi
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
2020-06-04 09:15:00
To może być prostsze, po prostu:
#!/usr/bin/env bash
set -x
# if local program 'foo' returns 1 (doesn't exist) then...
if ! type -P foo; then
echo 'crap, no foo'
else
echo 'sweet, we have foo!'
fi
Zmień foo
na vi
, aby drugi warunek wystrzelił.
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
2020-06-15 20:43:00
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'
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
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
Polecenie which
może być przydatne. człowiek, który
Zwraca 0, jeśli plik wykonywalny został znaleziony i zwraca 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 executable
2 if an invalid option is specified
Fajną rzeczą w which
jest to, że wykrywa, czy plik wykonywalny jest dostępny w środowisku, w którym jest uruchomiony which
- oszczędza to kilka problemów...
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
2020-01-16 03:15:08
Musiałem sprawdzić, czy Git został zainstalowany w ramach wdrażania naszego serwera CI. Mój ostatni skrypt Bash wyglądał następująco (Ubuntu server):
if ! builtin type -p git &>/dev/null; then
sudo apt-get -y install git-core
fi
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
2020-01-16 03:27:26
Aby naśladować Basha type -P cmd
, Możemy użyć standardu 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; }
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
2020-01-16 03:28:20
Jeśli nie ma dostępnych zewnętrznych poleceń 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 v10.6.8 (Snow Leopard) używanie Bash 4.2.24 (2) command -v ls
nie pasuje do przeniesionego /bin/ls-temp
.
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
2020-01-16 03:47:03
/ Align = "left" /
Sprawdzam tylko czy Komenda którą wykonuję zwraca kod błędu. Jeśli zwróci 0 oznacza to, że program jest zainstalowany. Ponadto możesz użyć tego do sprawdzenia wyjścia skryptu. Weźmy na przykład ten skrypt.
Foo.sh
#!/bin/bash
echo "hello world"
exit 1 # throw some error code
Przykłady:
# outputs something bad... and exits
bash foo.sh $? -eq 0 || echo "something bad happened. not installed" ; exit 1
# does NOT outputs nothing nor exits because dotnet is installed on my machine
dotnet --version $? -eq 0 || echo "something bad happened. not installed" ; exit 1
W zasadzie wszystko, co robisz, to sprawdzanie kodu zakończenia uruchomienia polecenia. najbardziej akceptowana odpowiedź na to pytanie zwróci true, nawet jeśli Komenda zakończy kod nie jest 0.
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
2020-10-14 20:10:26