Bash's return()können nur numerische Argumente zurückgeben. In jedem Fall wird standardmäßig der Exit-Status des letzten Befehlslaufs zurückgegeben. Alles was Sie wirklich brauchen ist:
Sie müssen keinen explizit zurückzugebenden Wert festlegen, da standardmäßig eine Funktion zurückgegeben wird $?. Dies funktioniert jedoch nicht, wenn der erste aptBefehl fehlgeschlagen ist und Sie nicht in die ifSchleife gegangen sind . Verwenden Sie Folgendes, um es robuster zu machen:
#!/usr/bin/env bash
install_auto(){
apt-get -h >/dev/null 2>&1
ret=$?if[ $ret -eq 0];then## If this is executed, the else is ignored and $? will be## returned. Here, $?will be the exit status of this command
sudo apt-get install --assume-yes $@else## Else, return the exit value of the first apt-getreturn $retfi}
Die allgemeine Regel lautet, dass Sie den Exit-Status in einer Variablen speichern und die Variable zurückgeben müssen, damit eine Funktion den Beendigungsstatus eines bestimmten Jobs und nicht unbedingt den zuletzt ausgeführten zurückgibt:
function foo(){
run_a_command arg1 arg2 argN## Save the command's exit status into a variable
return_value= $?[the rest of the function goes here]## return the variablereturn $return_value}
EDIT: Wie @gniourf_gniourf in den Kommentaren betonte, können Sie das Ganze erheblich vereinfachen, indem Sie &&:
Entschuldigung, mein Beispiel war nicht klar genug. Ich benötige eine return-Anweisung (oder eine äquivalente Logik) in meinem eigentlichen Skript, damit Dinge, die dieser Anweisung folgen, nicht ausgeführt werden, wenn apt-get auf diesem System vorhanden war. Wenn apt-get nicht vorhanden ist, sucht es nach Zypper usw. Ich denke, das Hinzufügen return $?in der nächsten Zeile Ihres Beispiels nach sudo apt-get ...könnte ausreichen. Ist das richtig? Vielen Dank
MountainX
@MountainX siehe aktualisierte Antwort. Wenn Sie es geschrieben haben (und wie ich mein Beispiel geschrieben habe), wenn das aptfehlschlägt, wird sein Exit-Status zurückgegeben und die Funktion wird beendet, wobei der Exit-Wert von zurückgegeben wird at-get. Ist es nicht das, was du brauchst?
Terdon
2
Die retVariable ist nutzlos. apt-get -h > /dev/null 2>&1 && sudo apt-get install --assume-yes "$@"würde das gleiche tun. Oh, und verwenden Sie mehr Anführungszeichen, besonders für$@
gniourf_gniourf
@gniourf_gniourf ja in der Tat, Antwort aktualisiert.
Terdon
Danke für die Rückmeldung. Ich habe meine gesamte Funktion eingefügt, als mir klar wurde, dass mein vereinfachtes Beispiel nicht ausreicht. Ich freue mich über weitere Kommentare.
MountainX
1
Der Vollständigkeit halber ist hier meine eigentliche Funktion mit einigen Änderungen, wie von @terdon und @gniourf_gniourf vorgeschlagen:
install_auto(){if[! $# -gt 0 ] ; then
echo "usage: $0 package_name [package_name ...]"fi
apt-get -h >/dev/null 2>&1if[ $?-eq 0];thenif[-f "$@"]||[["$@"=~'/']];then
sudo gdebi -n "$@"return $?else
sudo apt-get install --assume-yes "$@"return $?fifi
zypper help >/dev/null 2>&1if[ $?-eq 0];then
sudo zypper --non-interactive --no-gpg-checks --quiet install --auto-agree-with-licenses "$@"return $?fi#may check other package managers in the future
echo "ERROR: package manager not found"return255}
Das cmd; if [ $? -eq 0 ]; then ...Konstrukt wird im Allgemeinen besser ausgedrückt als if cmd; then ...oder sogar nur, cmd && ...wenn der "dann" -Teil nur ein einfacher Befehl ist.
return $?
in der nächsten Zeile Ihres Beispiels nachsudo apt-get ...
könnte ausreichen. Ist das richtig? Vielen Dankapt
fehlschlägt, wird sein Exit-Status zurückgegeben und die Funktion wird beendet, wobei der Exit-Wert von zurückgegeben wirdat-get
. Ist es nicht das, was du brauchst?ret
Variable ist nutzlos.apt-get -h > /dev/null 2>&1 && sudo apt-get install --assume-yes "$@"
würde das gleiche tun. Oh, und verwenden Sie mehr Anführungszeichen, besonders für$@
Der Vollständigkeit halber ist hier meine eigentliche Funktion mit einigen Änderungen, wie von @terdon und @gniourf_gniourf vorgeschlagen:
Ich freue mich über weitere Vorschläge.
quelle
cmd; if [ $? -eq 0 ]; then ...
Konstrukt wird im Allgemeinen besser ausgedrückt alsif cmd; then ...
oder sogar nur,cmd && ...
wenn der "dann" -Teil nur ein einfacher Befehl ist.