2010-08-20 3 views
32

Also meine Frage ist, wie kann ich übergeben ein Dateiargument zu meinem Bash-Skript mit einem Terminal-Befehl in Linux? Im Moment versuche ich ein Programm in bash zu erstellen, das ein Dateiargument vom Terminal nehmen und als Variable in meinem Programm verwenden kann. Zum Beispiel führe ich myprogram --file=/path/to/file in Terminal.Wie kann ich ein Dateiargument mit einem Terminal-Befehl unter Linux an mein Bash-Skript übergeben?

Mein Programm

#!/bin/bash  
File=(the path from the argument) 
externalprogram $File (other parameters) 

Wie kann ich das mit meinem Programm erreichen?

Antwort

42

Es wird einfacher (und mehr „richtige“, siehe unten), wenn Sie nur Ihr Skript als

myprogram /path/to/file 

Dann führen Sie den Pfad innerhalb des Skripts als $1 zugreifen können (zum Argument # 1, ähnlich ist $2 Argument # 2, usw.)

file="$1" 
externalprogram "$file" [other parameters] 

Oder nur

externalprogram "$1" [otherparameters] 

Wenn Sie den Pfad von etwas wie --file=/path/to/file extrahieren möchten, wird dies normalerweise mit der Shell-Funktion getopts gemacht. Aber das ist komplizierter als nur Referenzieren $1, und außerdem sind Schalter wie --file= optional sein sollen. Ich nehme an, Ihr Skript erfordert einen Dateinamen zur Verfügung gestellt werden, so ist es nicht sinnvoll, es in einer Option zu übergeben.

+3

Beachten Sie, dass alle Parameter Erweiterungen müssen zitiert werden, einschließlich '$ file'. – Philipp

+0

Gibt es eine Möglichkeit, die Methode --file zu implementieren? Ich möchte das tun, denn wenn es ohne das Argument --file ausgeführt wird, könnte das Programm den Benutzer fragen, welche Datei gewählt werden soll. Es wird das Programm auf diese Weise straffen. – AZorin

+2

Normalerweise überprüfen Sie einfach, ob der Benutzer einen Dateinamen angegeben hat (der Parameter '#' enthält die Anzahl der Positionsargumente), und verwenden Sie die Standardeingabe, wenn keine Datei oder '-' angegeben wurde. Wenn Sie die Syntax '--file =' verwenden möchten, verwenden Sie eine 'case' Anweisung. – Philipp

7

Bash unterstützt ein Konzept namens "Positional Parameters". Diese Positionsparameter repräsentieren Argumente, die in der Befehlszeile angegeben werden, wenn ein Bash-Skript aufgerufen wird.

Positionsparameter werden mit den Namen $0, $1, $2 ... und so weiter bezeichnet. $0 ist der Name des Skripts selbst, $1 ist das erste Argument für das Skript, $2 der zweite usw. $* stellt alle Positionsparameter mit Ausnahme von $0 dar (d. H. Beginnend mit $1).

Ein Beispiel:

#!/bin/bash 
FILE="$1" 
externalprogram "$FILE" <other-parameters> 
+1

'$ FILE' muss zitiert werden. – Philipp

+2

Ja, Sie haben recht, in diesem Fall erwarten wir, dass '$ 1' einen Dateinamen enthält, der in Anführungszeichen gesetzt werden sollte, um eine Worttrennung zu vermeiden, falls der Dateiname ein oder mehrere Leerzeichen enthält. Aber ist das Notieren von Positionsparametern * immer * notwendig? –

+0

Ich denke, es ist einfacher, immer alle Variablen zu zitieren, als zu erraten, ob sie Zitate sein müssen. Positionsargumente sind Benutzereingaben, und Benutzer können alles eingeben. Wenn also nicht dokumentiert wird, dass ein Argument eine Worttrennung erfährt, muss es zitiert werden. Technisch gesehen müssen Variablen nicht nach '=' und innerhalb von [[...]] 'zitiert werden, aber es ist einfacher, sie zu zitieren, als sich daran zu erinnern, wo die Wortaufteilung nicht ausgeführt wird. – Philipp

2

Angenommen, Sie tun, wie David Zaslavsky vermuten lässt, so dass das erste Argument einfach ist das Programm auszuführen (keine Option-Parsing erforderlich), sind Sie mit der Frage zu tun wie man Argumente 2 an ein externes Programm weitergibt. Hier ist eine bequeme Art und Weise:.

#!/bin/bash 
ext_program="$1" 
shift 
"$ext_program" "[email protected]" 

Die shift wird das erste Argument entfernen, um den Rest Umbenennung ($2 wird $1, and so on). $ @ `bezieht sich auf die Argumente, als ein Array von Wörtern (es muss angegeben werden)

Wenn Sie Ihre --file Syntax haben müssen (zum Beispiel, wenn ein Standardprogramm ausgeführt wird, also muss der Benutzer nicht unbedingt einen angeben), ersetzen Sie einfach ext_program="$1" durch das Parsen von $1, was Sie tun müssen, vielleicht mit getopt oder getopts.

Wenn Sie Ihre eigene Rolle wollen, nur für einen bestimmten Fall könnten Sie so etwas tun:

if [ "$#" -gt 0 -a "${1:0:6}" == "--file" ]; then 
    ext_program="${1:7}" 
else 
    ext_program="default program" 
fi 
+0

+1 zum Zitieren. Aber weder 'getopt' noch' getopts' können Argumente im GNU-Stil parsen. – Philipp

+0

@Philipp: getopts kann nicht, aber getopt kann definitiv, auf meinem System sowieso. Vermutlich kommt das daher, dass es eine GNU- und eine Nicht-GNU-Version der C-Funktion 'getopt' gibt. – Cascabel

17

Sie getopt verwenden können Parameter in Ihrem Bash-Skript zu behandeln. Es gibt nicht viele Erklärungen für getopt da draußen. hier ist ein Beispiel:

#!/bin/sh 

OPTIONS=$(getopt -o hf:gb -l help,file:,foo,bar -- "[email protected]") 

if [ $? -ne 0 ]; then 
    echo "getopt error" 
    exit 1 
fi 

eval set -- $OPTIONS 

while true; do 
    case "$1" in 
    -h|--help) HELP=1 ;; 
    -f|--file) FILE="$2" ; shift ;; 
    -g|--foo) FOO=1 ;; 
    -b|--bar) BAR=1 ;; 
    --)  shift ; break ;; 
    *)   echo "unknown option: $1" ; exit 1 ;; 
    esac 
    shift 
done 

if [ $# -ne 0 ]; then 
    echo "unknown option(s): [email protected]" 
    exit 1 
fi 

echo "help: $HELP" 
echo "file: $FILE" 
echo "foo: $FOO" 
echo "bar: $BAR" 

siehe auch:

+1

... großartige Erklärung – Jonathan

Verwandte Themen