Wie würde ich überprüfen, ob ein Programm vorhanden ist, das entweder einen Fehler zurückgibt und beendet oder mit dem Skript fortfährt?
Es scheint, als sollte es einfach sein, aber es hat mich verblüfft.
Wie würde ich überprüfen, ob ein Programm vorhanden ist, das entweder einen Fehler zurückgibt und beendet oder mit dem Skript fortfährt?
Es scheint, als sollte es einfach sein, aber es hat mich verblüfft.
Antworten:
POSIX-kompatibel:
command -v <the_command>
Für Bash-spezifische Umgebungen:
hash <the_command> # For regular commands. Or...
type <the_command> # To check built-ins and keywords
Vermeiden Sie which
. Es ist nicht nur ein externer Prozess, den Sie starten, um sehr wenig zu tun (was bedeutet hash
, dass integrierte Funktionen viel billiger sind type
oder command
viel billiger sind), sondern Sie können sich auch darauf verlassen, dass die integrierten Funktionen tatsächlich das tun, was Sie möchten, während die Auswirkungen externer Befehle leicht davon abweichen können System zu System.
Warum sich darum kümmern?
which
, der nicht einmal einen Exit-Status festlegt , was bedeutet, if which foo
dass er dort nicht einmal funktioniert und immer meldet, dass er foo
existiert, auch wenn dies nicht der Fall ist (beachten Sie, dass einige POSIX-Shells dies anscheinend auch tun hash
).which
benutzerdefinierte und böse Dinge wie das Ändern der Ausgabe oder sogar das Einhängen in den Paketmanager.Also nicht benutzen which
. Verwenden Sie stattdessen eine der folgenden Optionen:
$ 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; }
(Kleinere Randnotiz: Einige schlagen vor, dass 2>&-
es dasselbe ist, 2>/dev/null
aber kürzer - dies ist nicht wahr . 2>&-
Schließt FD 2, was einen Fehler im Programm verursacht, wenn versucht wird, in stderr zu schreiben, was sich stark vom erfolgreichen Schreiben und Verwerfen der Ausgabe unterscheidet (und gefährlich!))
Wenn Ihr Hash Bang ist /bin/sh
, sollten Sie sich darum kümmern, was POSIX sagt. type
und hash
‚s Exit - Codes sind nicht sehr gut von POSIX definiert, und hash
werden erfolgreich gesehen zu verlassen , wenn der Befehl nicht vorhanden ist (habe dies nicht gesehen type
noch) nicht . command
Der Exit-Status von POSIX ist gut definiert, sodass er wahrscheinlich am sichersten zu verwenden ist.
Wenn Ihr Skript jedoch verwendet bash
, spielen POSIX-Regeln keine Rolle mehr und beides type
und hash
sind absolut sicher zu verwenden. type
Jetzt muss -P
nur noch das PATH
und gesucht werdenhash
hat den Nebeneffekt, dass der Speicherort des Befehls gehasht wird (für eine schnellere Suche bei der nächsten Verwendung), was normalerweise eine gute Sache ist, da Sie wahrscheinlich nach seiner Existenz , um ihn tatsächlich zu verwenden .
Als einfaches Beispiel ist hier eine Funktion, die ausgeführt wird, gdate
wenn sie existiert, andernfalls date
:
gnudate() {
if hash gdate 2>/dev/null; then
gdate "$@"
else
date "$@"
fi
}
2>&-
("Close Output File Descriptor 2", was stderr ist) hat das gleiche Ergebnis wie 2> /dev/null
; 2) >&2
ist eine Verknüpfung für 1>&2
, die Sie möglicherweise als "stdout nach stderr umleiten" erkennen. Weitere Informationen finden Sie auf der I / O-Umleitungsseite des Advanced Bash Scripting Guide .
while read element ; do .. done <<< $(echo ${ArrayVar[*]})
, for word in $(fgrep -l $ORIGINAL *.txt)
, ls -l "$directory" | sed 1d
, {{für einen in seq $BEGIN $END
}}, ... Viele haben versucht , die Autoren zu kontaktieren und Verbesserungen vorzuschlagen , aber es ist kein Wiki und Anfragen haben auf taube Ohren gelandet.
2>&-
ist nicht dasselbe wie 2>/dev/null
. Ersteres schließt den Dateideskriptor, während letzteres ihn einfach umleitet /dev/null
. Möglicherweise wird kein Fehler angezeigt, da das Programm versucht, Sie auf stderr darüber zu informieren, dass stderr geschlossen ist.
Das Folgende ist eine tragbare Methode, um zu überprüfen, ob ein Befehl in vorhanden $PATH
und ausführbar ist:
[ -x "$(command -v foo)" ]
Beispiel:
if ! [ -x "$(command -v git)" ]; then
echo 'Error: git is not installed.' >&2
exit 1
fi
Die Prüfung der ausführbaren Datei ist erforderlich, da bash eine nicht ausführbare Datei zurückgibt, wenn keine ausführbare Datei mit diesem Namen in gefunden wird $PATH
.
Beachten Sie auch, dass, wenn eine nicht ausführbare Datei mit demselben Namen wie die ausführbare Datei früher vorhanden ist $PATH
, dash die erstere zurückgibt, obwohl die letztere ausgeführt wird. Dies ist ein Fehler und verstößt gegen den POSIX-Standard. [ Fehlerbericht ] [ Standard ]
Darüber hinaus schlägt dies fehl, wenn der gesuchte Befehl als Alias definiert wurde.
command -v
ein Pfad auch für eine nicht ausführbare Datei erstellt? Das heißt, das -x wirklich notwendig?
-x
testet, ob die Datei ausführbar ist, was die Frage war.
command
es selbst testen wird, ob es ausführbar ist - nicht wahr ?
$PATH
beim Ausführen eines Befehls nicht ausführbare Dateien . Das Verhalten von command -v
ist jedoch sehr inkonsistent. Im Bindestrich wird die erste übereinstimmende Datei zurückgegeben $PATH
, unabhängig davon, ob sie ausführbar ist oder nicht. In bash gibt es die erste ausführbare Übereinstimmung in zurück $PATH
, aber wenn es keine gibt, kann es eine nicht ausführbare Datei zurückgeben. Und in zsh wird niemals eine nicht ausführbare Datei zurückgegeben.
dash
ist es das einzige von diesen drei, das nicht POSIX-konform ist. [ -x "$(command -v COMMANDNAME)"]
wird in den anderen beiden arbeiten. Es sieht so aus, als ob dieser Fehler bereits gemeldet wurde, aber noch keine Antworten erhalten hat: bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264
Ich bin mit lhunath einverstanden, von der Verwendung abzuraten which
, und seine Lösung ist für Bash-Benutzer vollkommen gültig . Um jedoch tragbarer zu sein, command -v
sollte stattdessen Folgendes verwendet werden:
$ command -v foo >/dev/null 2>&1 || { echo "I require foo but it's not installed. Aborting." >&2; exit 1; }
Der Befehl command
ist POSIX-kompatibel. Die Spezifikation finden Sie hier: Befehl - Führen Sie einen einfachen Befehl aus
Hinweis: type
Ist POSIX-kompatibel, jedoch type -P
nicht.
exit 1;
tötet ein xterm, wenn es von dort aus aufgerufen wird.
&>/dev/null
. Ich stimme Ihnen jedoch zu, was wirklich wichtig ist, ist die Portabilität. Ich habe meine Antwort entsprechend bearbeitet und verwende jetzt die Standard-Weiterleitung >/dev/null 2>&1
.
In meiner .bashrc ist eine Funktion definiert, die dies erleichtert.
command_exists () {
type "$1" &> /dev/null ;
}
Hier ist ein Beispiel, wie es verwendet wird (von meinem .bash_profile
.)
if command_exists mvim ; then
export VISUAL="mvim --nofork"
fi
&>
?
&>
leitet sowohl stdout als auch stderr zusammen um.
&>
ist möglicherweise in Ihrer Version von Bash nicht verfügbar. Marcellos Code sollte gut funktionieren. es macht das gleiche.
then
. Sehen Sie diese Antwort , wenn Sie die ausführbare Datei benötigen in existieren $PATH
.
Dies hängt davon ab, ob Sie wissen möchten, ob es in einem der Verzeichnisse der $PATH
Variablen vorhanden ist oder ob Sie den absoluten Speicherort kennen. Wenn Sie wissen möchten, ob es sich um eine $PATH
Variable handelt, verwenden Sie
if which programname >/dev/null; then
echo exists
else
echo does not exist
fi
andernfalls verwenden
if [ -x /path/to/programname ]; then
echo exists
else
echo does not exist
fi
Die Umleitung zu /dev/null/
im ersten Beispiel unterdrückt die Ausgabe des which
Programms.
Um die Antworten von @ lhunath und @ GregV zu erweitern, hier der Code für die Personen, die diesen Scheck einfach in eine if
Erklärung einfügen möchten :
exists()
{
command -v "$1" >/dev/null 2>&1
}
So verwenden Sie es:
if exists bash; then
echo 'Bash exists!'
else
echo 'Your system does not have Bash'
fi
command
auch für Aliase erfolgreich ist, was möglicherweise etwas uninteressant ist. Das Überprüfen der Existenz in einer interaktiven Shell führt zu anderen Ergebnissen als beim Verschieben in ein Skript.
shopt -u expand_aliases
Aliase zum Ignorieren / Ausblenden getestet und verwendet (wie alias ls='ls -F'
in einer anderen Antwort erwähnt) und shopt -s expand_aliases
sie über aufgelöst command -v
. Daher sollte es möglicherweise vor der Prüfung festgelegt und danach deaktiviert werden. Dies kann sich jedoch auf den Funktionsrückgabewert auswirken, wenn Sie die Ausgabe des Befehlsaufrufs nicht explizit erfassen und zurückgeben.
Versuchen Sie es mit:
test -x filename
oder
[ -x filename ]
Aus der Bash-Manpage unter Bedingte Ausdrücke :
-x file True if file exists and is executable.
So verwenden Sie hash
, wie @lhunath vorschlägt , in einem Bash-Skript:
hash foo &> /dev/null
if [ $? -eq 1 ]; then
echo >&2 "foo not found."
fi
Dieses Skript wird ausgeführt hash
und prüft dann, ob der Exit-Code des letzten Befehls, der darin gespeicherte Wert $?
, gleich ist 1
. Wenn hash
nicht gefunden wird foo
, lautet der Exit-Code 1
. Wenn foo
vorhanden, lautet der Exit-Code 0
.
&> /dev/null
Leitet Standardfehler und Standardausgabe von hash
so um, dass sie nicht auf dem Bildschirm angezeigt werden, und echo >&2
schreibt die Nachricht in Standardfehler.
if hash foo &> /dev/null; then ...
?
Ich habe nie die vorherigen Antworten erhalten, um an der Box zu arbeiten, auf die ich Zugriff habe. Zum einen type
wurde installiert (tun was more
tut). Die eingebaute Direktive wird also benötigt. Dieser Befehl funktioniert bei mir:
if [ `builtin type -p vim` ]; then echo "TRUE"; else echo "FALSE"; fi
if
Syntax, verwenden Sie einfach if builtin type -p vim; then ...
. Und die Backticks sind wirklich alte und veraltete Syntax, $()
wird sogar von sh
allen modernen Systemen unterstützt.
Suchen Sie nach mehreren Abhängigkeiten und informieren Sie den Endbenutzer über den Status
for cmd in latex pandoc; do
printf '%-10s' "$cmd"
if hash "$cmd" 2>/dev/null; then
echo OK
else
echo missing
fi
done
Beispielausgabe:
latex OK
pandoc missing
Stellen Sie die 10
auf die maximale Befehlslänge ein. Es ist nicht automatisch, da ich keine nicht ausführliche POSIX-Methode dafür sehe:
Wie kann ich die Spalten einer durch Leerzeichen getrennten Tabelle in Bash ausrichten?
Überprüfen Sie, ob einige apt
Pakete mit dpkg -s
installiert sind, und installieren Sie sie anderweitig .
Es wurde bereits erwähnt unter: Wie kann ich anhand eines Bash-Skripts überprüfen, ob ein Programm vorhanden ist?
column -t
leiten Sie Ihre for-Schleife an (Teil von util-linux).
Wenn Sie prüfen, ob ein Programm vorhanden ist, werden Sie es wahrscheinlich trotzdem später ausführen. Warum nicht gleich versuchen, es auszuführen?
if foo --version >/dev/null 2>&1; then
echo Found
else
echo Not found
fi
Es ist eine vertrauenswürdigere Überprüfung, ob das Programm ausgeführt wird, als nur PATH-Verzeichnisse und Dateiberechtigungen zu betrachten.
Außerdem können Sie mit Ihrem Programm einige nützliche Ergebnisse erzielen, z. B. die Version.
Die Nachteile sind natürlich, dass einige Programme schwer zu starten sein können und andere keine --version
Option zum sofortigen (und erfolgreichen) Beenden haben.
hash foo 2>/dev/null
: funktioniert mit Z Shell (Zsh), Bash, Dash und Ash .
type -p foo
: Es scheint mit Z-Shell, Bash und Ash ( BusyBox ) zu funktionieren , aber nicht mit Dash (es wird -p
als Argument interpretiert ).
command -v foo
: Funktioniert mit Z-Shell, Bash, Dash, aber nicht mit Ash (BusyBox) ( -ash: command: not found
).
Beachten Sie auch, dass builtin
dies mit Asche und Dash nicht möglich ist.
Verwenden Sie Bash Builtins, wenn Sie können:
which programname
...
type -P programname
which
ist kein Bash eingebaut.
-P
das nicht POSIX ist. Warum wird type -P
bevorzugt?
Der Befehl -v
funktioniert einwandfrei, wenn die Option POSIX_BUILTINS für festgelegt ist<command>
Test kann er fehlschlagen. (Es hat jahrelang bei mir funktioniert, aber ich bin kürzlich auf eines gestoßen, bei dem es nicht funktioniert hat.)
Ich finde Folgendes ausfallsicherer:
test -x $(which <command>)
Da es auf drei Dinge testet: Pfad, Existenz und Ausführungsberechtigung.
test -x $(which ls)
Gibt 0 zurück, test -x $(which sudo)
obwohl dies ls
installiert und ausführbar ist und sudo
nicht einmal in dem Docker-Container installiert ist, in dem ich ausgeführt werde.
test -x "$(which <command>)"
ls
ist Alias? Ich glaube nicht, dass es funktionieren würde, wenn der Befehl Parameter hat.
Für Interessenten funktioniert keine der Methoden in den vorherigen Antworten, wenn Sie eine installierte Bibliothek erkennen möchten. Ich kann mir vorstellen, dass Sie entweder den Pfad physisch überprüfen müssen (möglicherweise auf Header-Dateien und dergleichen) oder so etwas (wenn Sie sich auf einer Debian-basierten Distribution befinden):
dpkg --status libdb-dev | grep -q not-installed
if [ $? -eq 0 ]; then
apt-get install libdb-dev
fi
Wie Sie oben sehen können, bedeutet eine "0" -Antwort aus der Abfrage, dass das Paket nicht installiert ist. Dies ist eine Funktion von "grep" - eine "0" bedeutet, dass eine Übereinstimmung gefunden wurde, eine "1" bedeutet, dass keine Übereinstimmung gefunden wurde.
cmd; if [ $? -eq 0 ]; then
sollte jedoch if cmd; then
dpkg
oderapt
Hier gibt es eine Menge Optionen, aber ich war überrascht, dass es keine schnellen Einzeiler gab. Folgendes habe ich zu Beginn meiner Skripte verwendet:
[[ "$(command -v mvn)" ]] || { echo "mvn is not installed" 1>&2 ; exit 1; }
[[ "$(command -v java)" ]] || { echo "java is not installed" 1>&2 ; exit 1; }
Dies basiert auf der hier ausgewählten Antwort und einer anderen Quelle.
Ich würde sagen, es gibt keinen tragbaren und 100% zuverlässigen Weg, weil es baumelt alias
. Zum Beispiel:
alias john='ls --color'
alias paul='george -F'
alias george='ls -h'
alias ringo=/
Natürlich ist nur der letzte problematisch (keine Beleidigung für Ringo!). Aber alle von ihnen sind alias
aus der Sicht von gültig command -v
.
Um baumelnde wie abzulehnen ringo
, müssen wir die Ausgabe des eingebauten Shell- alias
Befehls analysieren und in sie zurückgreifen ( command -v
ist hier nicht überlegen alias
). Es gibt keine tragbare Lösung dafür und sogar eine Bash- spezifische Lösung ist ziemlich langwierig.
Beachten Sie, dass eine solche Lösung bedingungslos ablehnt alias ls='ls -F'
:
test() { command -v $1 | grep -qv alias }
shopt -u expand_aliases
diese Aliase getestet und mit ignoriert / versteckt und shopt -s expand_aliases
zeige sie über command -v
.
Dies zeigt je nach Speicherort an, ob das Programm vorhanden ist oder nicht:
if [ -x /usr/bin/yum ]; then
echo "This is Centos"
fi
Der which
Befehl könnte nützlich sein. Mann welcher
Es gibt 0 zurück, wenn die ausführbare Datei gefunden wird, und 1, wenn sie nicht gefunden wird oder nicht ausführbar ist:
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
Das Schöne daran which
ist, dass es herausfindet, ob die ausführbare Datei in der Umgebung verfügbar ist, in der sie ausgeführt which
wird - es erspart ein paar Probleme ...
Mein Setup für einen Debian- Server:
Ich hatte das Problem, wenn mehrere Pakete den gleichen Namen enthielten.
Zum Beispiel apache2
. Das war also meine Lösung:
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
}
Wenn Sie Jungs / Mädels die Antworten hier nicht zum Laufen bringen können und sich die Haare aus dem Rücken ziehen, versuchen Sie, denselben Befehl mit auszuführen bash -c
. Schauen Sie sich dieses somnambuläre Delirium an. Dies ist, was wirklich passiert, wenn Sie $ (Unterbefehl) ausführen:
Zuerst. Es kann Ihnen eine völlig andere Ausgabe geben.
$ command -v ls
alias ls='ls --color=auto'
$ bash -c "command -v ls"
/bin/ls
Zweite. Es kann Ihnen überhaupt keine Ausgabe geben.
$ command -v nvm
nvm
$ bash -c "command -v nvm"
$ bash -c "nvm --help"
bash: nvm: command not found
.bashrc
ich ein [ -z "$PS1" ] && return
vorangestelltes, # If not running interactively, don't do anything
also denke ich, das ist ein Grund, warum selbst die explizite Beschaffung von bashrc im nicht interaktiven Modus nicht hilft. Das Problem kann durch den Aufruf eines Skripts mit einem workarounded werden ss64.com/bash/source.html Punkt - Operator , . ./script.sh
aber das ist nicht eine Sache erinnern möchte jedes Mal eingeben.
Die Hash-Variante hat eine Gefahr: In der Kommandozeile können Sie beispielsweise eingeben
one_folder/process
Prozess ausführen lassen. Dazu muss sich der übergeordnete Ordner von one_folder in $ PATH befinden . Wenn Sie jedoch versuchen, diesen Befehl zu hashen, ist er immer erfolgreich:
hash one_folder/process; echo $? # will always output '0'
$PATH
" - Dies ist völlig ungenau. Versuch es. Damit dies funktioniert, muss sich one_folder im aktuellen Verzeichnis befinden .
Ich unterstütze die Verwendung von "Befehl -v". ZB so:
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
Ich musste überprüfen, ob Git im Rahmen der Bereitstellung unseres CI- Servers installiert wurde . Mein letztes Bash-Skript war wie folgt (Ubuntu-Server):
if ! builtin type -p git &>/dev/null; then
sudo apt-get -y install git-core
fi
sudo
: Ohne die Bedingung würde es immer anhalten und nach dem Passwort fragen (es sei denn, Sie haben kürzlich einen Sudo gemacht). Übrigens kann es nützlich sein, sudo -p "Type your password to install missing git-core: "
die Eingabeaufforderung nicht aus heiterem Himmel zu erhalten.
Um Bashs nachzuahmen type -P cmd
, können wir POSIX-konform verwenden 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; }
type
scheint zu sein , builtin
in den meisten Schalen so nicht funktionieren kann , weil env
Anwendungen execvp
laufen command
so command
kann ein nicht sein builtin
(und die builtin
in der gleichen Umgebung wird immer ausgeführt werden). Dies nicht für mich in bash
, ksh93
, zsh
, busybox [a]sh
und dash
alle liefern type
als Shell - builtin.
Wenn kein externer type
Befehl verfügbar ist (wie hier als selbstverständlich vorausgesetzt ), können wir POSIX-konform verwenden 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
Zumindest unter Mac OS X 10.6.8 (Snow Leopard) stimmt die Verwendung von Bash 4.2.24 (2) command -v ls
nicht mit einem Verschieben überein /bin/ls-temp
.
Im Fall , dass Sie prüfen , ob ein Programm existiert und ist wirklich ein Programm, kein Bash eingebauten Befehl , dann command
, type
undhash
ist nicht für die Prüfung , wie sie für integrierte Befehle all return 0 Exit - Status zu eigen.
Zum Beispiel gibt es das Zeitprogramm , das bietet mehr die Eigenschaften als Zeit integrierten Befehl. Um zu überprüfen, ob das Programm vorhanden ist, würde ich die Verwendung wie im folgenden Beispiel vorschlagen :which
# 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
Ich wollte die gleiche Frage beantworten, aber innerhalb eines Makefiles laufen.
install:
@if [[ ! -x "$(shell command -v ghead)" ]]; then \
echo 'ghead does not exist. Please install it.'; \
exit -1; \
fi
Skript
#!/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"'
Ergebnis
✘ [ABRT]: notacmd: command does not exist
hits command
0 /usr/bin/bash
Fin.
Ich benutze das, weil es sehr einfach ist:
if [ `LANG=C type example 2>/dev/null|wc -l` = 1 ];then echo exists;else echo "not exists";fi
oder
if [ `LANG=C type example 2>/dev/null|wc -l` = 1 ];then
echo exists
else echo "not exists"
fi
Es verwendet den eingebauten Shell-Status und den Echo-Status der Programme für die Standardausgabe und nichts für den Standardfehler. Wenn andererseits ein Befehl nicht gefunden wird, wird der Status nur als Standardfehler angezeigt.
which
gibt für diese true zurück.type
ohne Argumente gibt zusätzlich true für reservierte Wörter und eingebaute Shell zurück. Wenn "Programm" "auslösbar in$PATH
" bedeutet, sehen Sie diese Antwort .