Skriptparameter in Bash

103

Ich versuche ein Shell-Skript zu erstellen, das wie folgt verwendet werden sollte:

ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

Das Skript konvertiert dann die Bilddatei in eine Textdatei. Folgendes habe ich mir bisher ausgedacht:

#!/bin/bash
export HOME=/home/kristoffer
/usr/local/bin/abbyyocr9 -rl Swedish -if ???fromvalue??? -of ???tovalue??? 2>&1

Aber ich weiß nicht, wie ich die -fromund -toWerte bekommen soll. Irgendwelche Ideen, wie es geht?

Kristoffer
quelle
6
Sie sollten tldp.org/LDP/Bash-Beginners-Guide/html/…
Mehul Rathod

Antworten:

124

Die Argumente, die Sie für ein Bashscript angeben, werden in den Variablen angezeigt $1und $2und $3wo sich die Nummer auf das Argument bezieht. $0ist der Befehl selbst.

Die Argumente sind durch Leerzeichen getrennt. Wenn Sie also das -fromund -toim Befehl angeben, werden sie auch in diesen Variablen angezeigt.

./ocrscript.sh -from /home/kristoffer/test.png -to /home/kristoffer/test.txt

Du wirst kriegen:

$0    # ocrscript.sh
$1    # -from
$2    # /home/kristoffer/test.png
$3    # -to
$4    # /home/kristoffer/test.txt

Es könnte einfacher sein, das -fromund das wegzulassen -to, wie:

ocrscript.sh /home/kristoffer/test.png /home/kristoffer/test.txt

Dann haben Sie:

$1    # /home/kristoffer/test.png
$2    # /home/kristoffer/test.txt

Der Nachteil ist, dass Sie es in der richtigen Reihenfolge liefern müssen. Es gibt Bibliotheken, die es einfacher machen können, benannte Argumente in der Befehlszeile zu analysieren, aber normalerweise sollten Sie für einfache Shell-Skripte nur den einfachen Weg verwenden, wenn dies kein Problem darstellt.

Dann können Sie tun:

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

Die doppelten Anführungszeichen um $1und und $2sind nicht immer erforderlich, werden jedoch empfohlen, da einige Zeichenfolgen nicht funktionieren, wenn Sie sie nicht zwischen doppelte Anführungszeichen setzen.

Gitaarik
quelle
69

Wenn Sie nicht vollständig an die Verwendung von "von" und "bis" als Optionsnamen gebunden sind, ist es ziemlich einfach, dies mit getopts zu implementieren :

while getopts f:t: opts; do
   case ${opts} in
      f) FROM_VAL=${OPTARG} ;;
      t) TO_VAL=${OPTARG} ;;
   esac
done

getopts ist ein Programm, das Befehlszeilenargumente verarbeitet und diese bequem für Sie analysiert.

f:t:Gibt an, dass Sie 2 Parameter erwarten, die Werte enthalten (angezeigt durch den Doppelpunkt). So etwas wie f:t:vsagt, dass dies -vnur als Flagge interpretiert wird.

optsHier wird der aktuelle Parameter gespeichert. In der caseAnweisung werden Sie dies verarbeiten.

${OPTARG}enthält den Wert nach dem Parameter. ${FROM_VAL}Zum Beispiel erhalten Sie den Wert, /home/kristoffer/test.pngwenn Sie Ihr Skript wie folgt ausgeführt haben :

ocrscript.sh -f /home/kristoffer/test.png -t /home/kristoffer/test.txt

Wie die anderen vorschlagen, sollten Sie, wenn Sie zum ersten Mal Bash-Skripte schreiben, einige Grundlagen wirklich nachlesen. Dies war nur eine kurze Anleitung zur Funktionsweise getopts.

Manny D.
quelle
1
Dies scheint eine lesbare Lösung zu sein. Wie würden Sie dann zwei Flags angeben?
Zelphir Kaltstahl
@Zelphir, Sie können zwei oder mehr Flags angeben, indem Sie einfach das ":" nach dem Flag weglassen. Zum Beispiel f:t:vswird-f some_f -t some_t -v -s
h_s
34

Verwenden Sie die Variablen "$1", "$2", "$3"und so weiter , um Zugang Argumente. Um auf alle zuzugreifen, können Sie verwenden "$@"oder die Anzahl der Argumente ermitteln $#(möglicherweise hilfreich, um nach zu wenigen oder zu vielen Argumenten zu suchen).

StianE
quelle
24

Ich musste sicherstellen, dass meine Skripte vollständig zwischen verschiedenen Maschinen, Shells und sogar Cygwin-Versionen portierbar sind. Außerdem sind meine Kollegen, für die ich die Skripte schreiben musste, Programmierer, und so habe ich Folgendes verwendet:

for ((i=1;i<=$#;i++)); 
do

    if [ ${!i} = "-s" ] 
    then ((i++)) 
        var1=${!i};

    elif [ ${!i} = "-log" ];
    then ((i++)) 
        logFile=${!i};  

    elif [ ${!i} = "-x" ];
    then ((i++)) 
        var2=${!i};    

    elif [ ${!i} = "-p" ]; 
    then ((i++)) 
        var3=${!i};

    elif [ ${!i} = "-b" ];
    then ((i++)) 
        var4=${!i};

    elif [ ${!i} = "-l" ];
    then ((i++)) 
        var5=${!i}; 

    elif [ ${!i} = "-a" ];
    then ((i++)) 
        var6=${!i};
    fi

done;

Begründung: Ich habe auch ein launcher.shSkript eingefügt, da die gesamte Operation mehrere Schritte hatte, die quasi unabhängig voneinander waren (ich sage "quasi", denn obwohl jedes Skript für sich ausgeführt werden konnte, wurden sie normalerweise alle zusammen ausgeführt ), und in zwei Tagen stellte ich fest, dass ungefähr die Hälfte meiner Kollegen, die Programmierer und alle waren, zu gut waren, um die Launcher-Datei zu verwenden, der "Verwendung" zu folgen oder die HILFE zu lesen, die jedes Mal angezeigt wurde, wenn sie etwas taten falsch und sie haben das Ganze durcheinander gebracht, Skripte mit Argumenten in der falschen Reihenfolge ausgeführt und sich darüber beschwert, dass die Skripte nicht richtig funktionierten. Da ich der Choleriker bin, habe ich beschlossen, alle meine Skripte zu überarbeiten, um sicherzustellen, dass sie kollegensicher sind. Das obige Codesegment war das erste, was.

user1628658
quelle
2
Ich mag das. Ich füge am Ende einen Abschnitt hinzu, "sonst echo" Ungültiges Argument: $ {! I} "((i ++)) fi"
CJBS
6

In bash $1wird das erste Argument an das Skript übergeben, das $2zweite und so weiter

/usr/local/bin/abbyyocr9 -rl Swedish -if "$1" -of "$2" 2>&1

So können Sie verwenden:

./your_script.sh some_source_file.png destination_file.txt

Erklärung zu doppelten Anführungszeichen;

Betrachten Sie drei Skripte:

# foo.sh
bash bar.sh $1

# cat foo2.sh
bash bar.sh "$1"

# bar.sh
echo "1-$1" "2-$2"

Rufen Sie nun auf:

$ bash foo.sh "a b"
1-a 2-b

$ bash foo2.sh "a b"
1-a b 2-

Wenn Sie aufrufen, foo.sh "a b"wird es aufgerufen bar.sh a b(zwei Argumente) und foo2.sh "a b"damit aufgerufen bar.sh "a b"(1 Argument). Denken Sie immer daran, wie Parameter in Bash übergeben und erweitert werden. Dies erspart Ihnen viel Kopfschmerzen.

Jakub M.
quelle