Bash: Nehmen Sie das erste Befehlszeilenargument und übergeben Sie den Rest

78

Beispiel:

check_prog hostname.com /bin/check_awesome -c 10 -w 13

check_remote -H $HOSTNAME -C "$ARGS"
#To be expanded as
check_remote -H hostname.com -C "/bin/check_awesome -c 10 -w 13"

Ich hoffe, dass das oben Gesagte Sinn macht. Die Argumente werden sich ändern, da ich dies für mehr als 20 Befehle verwenden werde. Es ist eine seltsame Methode, ein Programm zu verpacken, aber es ist zu umgehen. Ein paar Probleme mit ein paar Systemen, die wir hier verwenden (Ich muss Code aus den 70ern lieben).

Das obige könnte in Perl oder Python geschrieben werden, aber Bash wäre die bevorzugte Methode

user554005
quelle

Antworten:

103

Sie können Shift verwenden

Shift ist eine integrierte Shell, die mit den Positionsparametern arbeitet. Jedes Mal, wenn Sie die Verschiebung aufrufen, werden alle Positionsparameter um eins "verschoben". Aus $ 2 wird $ 1, aus $ 3 wird $ 2, aus $ 4 wird $ 3 und so weiter

Beispiel:

$ function foo() { echo $@; shift; echo $@; } 
$ foo 1 2 3
1 2 3
2 3
Ravi
quelle
9
Genial! Funktioniert wie ein Zauber echo $1 shift echo $* ist ein Beispiel dafür, wie man Shift für zukünftige Leute verwendet, die danach suchen, es ausführen ./script.sh cmd1 cmd2 cmd3 cmd4und es setzt $ 1 auf cmd1 und der Rest wird cmd2 cmd3 cmd4 sein, wie ich wollte
user554005
3
Und $#wird um 1 reduziert, es sei denn, es ist bereits 0. Sie können auch shiftein numerisches Argument angeben, um um mehr als eine Stelle zu verschieben.
Keith Thompson
8
@ user554005: Sie sollten fast immer echo "$@"anstelle echo $*oder echo "$*"seit dem nicht zitierten $*Formular und dem zitierten Formular die Argumente "reduzieren", die normalerweise nicht gewünscht werden.
Bis auf weiteres angehalten.
1
So typisch wäre die Verwendung SOME_VAR=$1; shift; some_cmd "$*". Jetzt some_cmdwird args 2..n übergeben. Funktioniert super ... Danke!
Brad Parks
5
@BradParks beim Übergeben von Dateinamen als Argumente, die von einem anderen Befehl gelesen werden, und wenn die Dateinamen Leerzeichen enthalten, möchten Sie dies, SOME_VAR=$1; shift; some_cmd "$@"da "$@"sichergestellt wird, dass maskierte Leerzeichen mit einem Backslash vor dem Leerzeichen übergeben werden. "$*"wird das \ Zeichen
löschen
11

Als Programmierer würde ich dringend davon abraten, shiftda Operationen, die den Status ändern, große Teile eines Skripts beeinflussen und das Verstehen, Ändern und Debuggen erschweren können: heat_smile:. Sie können stattdessen Folgendes verwenden:

#!/usr/bin/env bash

all_args=("$@")
first_arg=$1
second_args=$2
rest_args=("${all_args[@]:2}")

echo "${rest_args[@]}"
Abdullah
quelle
3
Ich würde dringend empfehlen, keine Liste von Argumenten in einer einfachen Zeichenfolgenvariablen zu speichern und / oder Variablen ohne doppelte Anführungszeichen zu erweitern (wie REST_ARGShier). Verwenden Sie ein Array (wie ALL_ARGS) und erweitern Sie es mit [@]doppelten Anführungszeichen.
Gordon Davisson
1
@ GordonDavisson Kannst du das bashSnippet mit deiner Empfehlung umschreiben oder ein anderes Snippet schreiben? Ich würde es sehr gerne besser verstehen und in einigen bashSkripten verwenden, an denen ich gerade arbeite. Vielen Dank im Voraus und weiter so!
Abdullah
3
Ich habe es bearbeitet, um mein empfohlenes Formular anzuzeigen. Das Speichern von Argumentlisten als Zeichenfolgen verliert die Unterscheidung zwischen mehreren Argumenten und einzelnen Argumenten, die Leerzeichen enthalten. Wenn Sie sie ohne doppelte Anführungszeichen erweitern, werden alle Leerzeichen (einschließlich derjenigen, die ursprünglich in Argumenten enthalten waren) aufgeteilt und alles erweitert, was wie ein Platzhalter für Dateinamen aussieht. Wenn Sie beispielsweise das Original als ausführen ./script "foo" "bar" "six * nine", wird "sechs <Liste der Dateien im aktuellen Verzeichnis> neun" gedruckt.
Gordon Davisson
2
Ich empfehle auch Variablennamen in Klein- oder Großbuchstaben, um Konflikte mit den verschiedenen Großbuchstaben mit besonderer Bedeutung zu vermeiden. Oh, und shellcheck.net ist gut darin, auf problematische Zitate und andere häufige Fehler hinzuweisen.
Gordon Davisson
Danke @GordonDavisson jetzt kann ich bessere BASH-Skripte schreiben und Leute, die meiner Antwort folgen, werden meine Fehler nicht wiederholen.
Abdullah