2016-07-25 13 views
1

Ich habe ein Bash-Skript, das ich zum Aufruf einer Java-Klasse verwenden, und ich übergebe zwei Argumente an diese Java-Klasse. Das erste Argument ($ 1) ist die Zeichenfolge, die ich übergebe und die den Namen einer Person enthält. Das zweite Argument ($ 2) ist der Vormonat als zweistellige Zahl (ebenfalls vom Benutzer übergeben).Übergabe eines Arguments in einem Bash-Skript

So wird die Java-Klasse wie folgt aufgerufen:

java -DCONFIG_DIR=... com.example.myapp.grades.gradingProcess $1 $2 

Aber jetzt, ich im zweiten Argument nicht der Benutzer möchte, und ich möchte den Monat, um zu bestimmen das Skript stattdessen zu übergeben.
Kann ich so etwas tun?

 month=`date +'%m' -d 'last month'` 

java -DCONFIG_DIR=... com.example.myapp.grades.gradingProcess $1 $month 

Und wenn ich meinen Skript ausführen, wird es so etwas wie dieses: ./myscript.sh ‚John‘ und nicht in einem zweistelligen Monat passieren, da ich es schon im Skript täte ?

Oder ist das nicht der richtige Weg? Tut mir leid, wenn das wie eine elementare Frage erscheint, ich versuche immer noch, mich an Bash-Skripte zu gewöhnen.

Vielen Dank?

+8

Ja, das sollte funktionieren. Ein Vorschlag: Wenn der Name einer Person ein Leerzeichen enthalten kann, müssen Sie $ 1 in doppelte Anführungszeichen setzen, damit sie als einzelnes Token übergeben wird. (Der Benutzer muss auch doppelte Anführungszeichen verwenden.) –

+1

@JuanTomas - Nicht nur * wenn * Sie Leerzeichen erwarten; Wenn Sie richtiges Quotieren durchführen, auch wenn Sie nicht erwarten, dass Sie es brauchen, werden Sie Bugs vermeiden, wenn Ihre Erwartungen falsch waren. (Ich habe tatsächlich ein massives Datenverlust-Ereignis gesehen, nachdem jemand entschieden hatte, keine Variablenerweiterung anzugeben, von der erwartet wurde, dass sie nur Dateinamen enthält, die zu '[0-9a-f] {24}' passen - ein Pufferüberlauf hat einen String mit einem Leerraum umgeben Sternchen in einen Namen, ein schlecht geschriebenes Skript versucht, diese Datei zu löschen, und Katastrophe folgte. –

+0

@JuanTomas, also muss ich $ Monat nicht in Anführungszeichen setzen, richtig? Auch weiß ich in der Tat, dass ich nur in einem Wort Namen (keine Leerzeichen) weitergeben werde, aber danke für die Köpfe hoch! Ich werde mir das merken. – user3266259

Antwort

2

Wenn Sie suchen, wie Sie einen Standardwert in der Shell angeben, gibt es einen Operator dafür.

month=${2-$(date -d 'last month' +%m)} 

java -stuff "$1" "$month" 

Nun, wenn es ein Wert in $2 ist, wird month zu, dass festgelegt werden; Andernfalls wird der Standardwert verwendet. Die Notation ${variable-value} liefert den Wert variable oder, wenn sie nicht gesetzt ist, den Text value. (Es gibt auch ${variable:-value} die value erzeugt, wenn variable gesetzt ist, aber leer als auch.)

(Diese in die java Befehlszeilen inlined werden konnten, sogar, wenn eine Variable es zu brechen ist wahrscheinlich besser für die Lesbarkeit.

java -stuff "$1" "${2-$(date -d 'last month' +%m)}" 

Beachten Sie auch, wie Sie grundsätzlich immer vom Benutzer bereitgestellte Variablen in doppelten Anführungszeichen.)

+0

Monat = $ {2 - $ (Datum -d 'letzter Monat' +% m)} Warum brauche ich die 2 in dieser Variable? – user3266259

+0

Wenn '$ 2' gesetzt ist,' Monat = $ 2'. Wenn '$ 2' nicht gesetzt ist, ist 'Monat = $ (Datum -d' letzter Monat '+% m)'. Ich versuchte es in der Antwort zu erklären; Ist es nicht klar? – tripleee

+0

Oh oops, habe das gerade gesehen. Vielen Dank. – user3266259

0

Ein paar Gedanken: Zeitzone, führende Null, und die Nutzung von Java statt bash.

Zeitzone

den aktuellen Monat Bestimmung erfordert einen aktuellen Datum. Das Ermitteln des aktuellen Datums erfordert eine Zeitzone.

Für einen bestimmten Zeitpunkt variiert das Datum auf der ganzen Welt. Zum Beispiel, ein paar Minuten nach Mitternacht in Paris ist ein neuer Tag noch "gestern" in Montréal.

Wenn Sie keine Zeitzone angeben, wird implizit eine aktuelle Standardzeitzone angewendet. Beachten Sie, dass sich der Standard jederzeit ändern kann. Und abhängig von der Standardeinstellung bedeutet das, dass Ihr Code auf eine Externalität außerhalb Ihrer direkten Kontrolle angewiesen ist. Und das bedeutet, dass die Ergebnisse variieren werden.

Also um das Ende/Anfang des Monats können Sie die falsche Monatszahl bekommen, die auf der Zeitzone im Spiel bestimmt.

Null Führende Oktal bedeuten kann in Java

Die %m Sie verwenden produziert zwei Ziffern. Zahlen mit einstelligen Zahlen haben eine führende Null. Beispiel: 09

Beachten Sie, dass in einigen Situationen in Java eine Zahl mit einer führenden Null als octal number (Basis 8) und nicht als Dezimalzahl (Basis 10) interpretiert wird.

Let Java die Arbeit

Ich schlage vor, macht es mehr Sinn die Java-Klasse die Arbeit der Bestimmung des Vormonats zu lassen. Die Bash-Zeile sollte die gewünschte/erwartete Zeitzone und nicht den Monat überschreiten.

ZoneId zoneId = ZoneId.of("America/Montreal") ; 
int previousMonthNumber = LocalDate.now(zoneId).minusMonths(1).getMonthValue() ; 

Tipp: In Java, noch besser ein Objekt aus dem Month Enumeration zu verwenden, anstatt eine bloße ganze Zahl ist. Macht Ihren Code selbstdokumentierender, typsicherer und garantiert gültige Werte.

Month month = LocalDate.now(zoneId).minusMonths(1).getMonth() ; 
+1

Es ist trivial, eine Zeitzone für den Befehl 'date' anzugeben; Setzen Sie einfach 'TZ' in der Befehlszeile. (Z. B. "TZ = Amerika/Lima Datum +% - m -d'letzter Monat"). – rici

+0

Es ist offensichtlich dramatisch zu sagen "der Standard kann sich jederzeit ändern". Wenn Sie eine Shell ausführen, wird die Umgebung vor dem Initialisieren der Shell erstellt und verbleibt so lange, bis die Shell beendet wird. Wenn der Administrator die globalen Standardeinstellungen in der Zwischenzeit ändert, bemerken Sie nur, wenn Sie eine neue Shell starten. – tripleee

+0

Mein Punkt ist, dass implizit auf die Standardzeitzone hat zwei Risiken: (a) Es ist eine Externalität außerhalb Ihrer Kontrolle (eine Tatsache, nicht zu dramatisch, wenn es Ihre Ergebnisse vollständig ändern kann), und (b) viele Programmierer tun Ich kenne oder denke nicht über die Zeitzone im Allgemeinen und noch weniger über die Bestimmung eines Monats nach. –