2009-04-18 5 views
12

Ich möchte in der Lage sein zu sagen, ob ein Befehl auf einem POSIX-System von einem Shell-Skript existiert.Finden Sie heraus, ob ein Befehl auf POSIX-System existiert

Unter Linux kann ich folgendes tun:

if which <command>; then 
    ...snip... 
fi 

jedoch, Solaris und MacOS which keinen Ausgang Fehlercode geben, wenn der Befehl nicht existiert, drucken sie nur eine Fehlermeldung an STDOUT.

Auch ich kürzlich entdeckt, dass die which Befehl selbst nicht POSIX ist (siehe http://www.opengroup.org/onlinepubs/009695399/utilities/)

Irgendwelche Ideen?

+2

verwandt: [Shell - Überprüfen Sie, ob ein Programm aus einem Bash-Skript besteht] (http://stackoverflow.com/questions/592620/check-if-a-program-exists-from-a-bash-script) – mrak

+0

Danke, war von unten nicht so klar, das hat mir @mrak 'if command -v dropbox geholfen; dann dropbox running' ... – Louis

Antwort

18

command -v ist ein POSIX-Befehl, der das tut, was tut.

Es ist definiert, dass> 0 zurückgegeben wird, wenn der Befehl nicht gefunden wird oder ein Fehler auftritt.

+2

I 100% stimmen mit 'command -v' überein, ich benutze es die ganze Zeit, um die Befehlsverfügbarkeit zu überprüfen. Zum Beispiel, Befehl -v CMD>/dev/null || echo 'CMD nicht gefunden'' Kein dummes 'wenn's erforderlich ist !! – TechZilla

+2

@TechZilla: Warum sind 'if' Anweisungen dumm? – dokaspar

+0

'if' ist nicht dumm, nur weil es ein' if' ist, es war in diesem Anwendungsfall dumm, da es überflüssig ist. Es gab keine Gruppierung und somit keinen zusätzlichen semantischen Wert, es wäre nur eine unnötige Neubewertung. Kann es trotzdem gerechtfertigt sein, absolut! Ein Zelot jeder Praxis kann fast alles rechtfertigen, und in diesem Fall ist die Konsequenz unbedeutend ... aber es bedeutet nicht, dass sie richtig sind, oder dass alle Dinge gleich sind. Im Allgemeinen mache ich die Praxis so, einen Befehl (Test eingeschlossen) mit einem einzelnen Fehlercode, keine if-Anweisung. Sobald Sie mehr bekommen, dann könnte 'if' mehr als vernünftig sein. – TechZilla

0

Sie könnten den stdout/stderr von "which" in eine Variable oder ein Array (mit Backticks) lesen, anstatt nach einem Beendigungscode zu suchen.

Wenn das System keinen "which" - oder "where" -Befehl hat, können Sie auch den Inhalt der $ PATH-Variablen abrufen, dann alle Verzeichnisse durchlaufen und nach der angegebenen ausführbaren Datei suchen. Das ist im Wesentlichen das, was es tut (obwohl es einige Caching/Optimierung von $ PATH-Ergebnissen verwenden könnte).

+0

Das Problem ist, dass sogar auf Systemen, die * haben * was, ich bin nicht garantiert es wird sogar * sein * keine Ausgabe ... Ich denke, ich könnte nur überprüfen, um zu sehen, dass es nicht "Sieht aus wie ein Pfad" ... – singpolyma

+0

Ah, [-x "' was aeiei' "] könnte funktionieren ... wieder unter der Annahme, was existiert ... – singpolyma

2

POSIX sagt: „If a command is not found, the exit status shall be 127.“ Also Sie

<command> 
if [ "${?}" = 127 ]; then 
    <handle not found> 
fi 

tun könnte, wenn Shell-Skripte zu schreiben, ist es oft erlaubt, eine Bash-Shell (#!/bin/bash) zu verlangen, denn ohne Arrays es ziemlich unmöglich ist, Argumente zu handhaben und/oder Dateinamen mit Leerzeichen korrekt. In diesem Fall ist die eingebaute Bash type -p gleichwertig, und weil es eingebaut ist, ist es tragbar.

+2

Typ ohne -p ist POSIX, aber POSIX garantiert das nicht interpretiert den nicht vorhandenen Befehl als Fehler. – singpolyma

+1

Bash ist ein Extra auf vielen Systemen. Der Versuch, herauszufinden, ob Dinge mit einer nicht standardmäßigen Shell unterstützt werden, ist nicht besonders gut. – dwc

+2

Unter Ubuntu haben sie versucht, für so viele Skripte wie möglich von Bash zu Dash zu wechseln (besonders beim Start), weil es kleiner und schneller zu starten ist. Und die BSDs werden in ihrer Basisinstallation nicht mit bash ausgeliefert. Genauso wenig wie die meisten System V-basierten Unixe. –

Verwandte Themen