2017-12-13 9 views
0

Ich versuche den ganzen Tag, um eine gute Möglichkeit zum Parsen einiger Zeichenfolgen mit einem Shell-Skript zu finden. Die Strings werden als Aufrufparameter für einige Anwendungen verwendet.Parsing komplexe Zeichenfolge mit Shell-Skript

sie wie folgt aussieht:

parsingParams -c "id=uid5 prog=/opt/bin/example arg=\"-D -t5 >/dev/null 1>&2\" info='fdhff fd'" start 

Ich bin nur zu verwenden, Shell-Skript erlaubt. Ich habe versucht, einige sed und Schnittbefehle zu verwenden, aber nichts funktioniert gut.

Meine Versuche sind wie:

prog=$(echo [email protected] | cut -d= -f3 | sed 's|\s.*$||') 

, die den korrekten Wert von prog zurück, sondern für den Wert von arg ich keinen guten Weg, um es zu bekommen finden. Der Parameter info ist optional und kann auch verlassen werden. kann jemand eine gute Idee haben, die dieses Problem lösen kann? vielen Dank im Voraus

+0

Bitte beschreiben Sie genau, was Sie wollen geparsten, das heißt, welche Teile Sie abgetrennten müssen. Das hat erhebliche Auswirkungen darauf, wie eine "richtige" Lösung aussehen würde. – DevSolar

+0

@DevSolar Ich möchte die Werte von ID, Prog, Arg und Info extrahieren. –

+0

Von 'parsingParams', was sie als' -c '... "' parameter? – DevSolar

Antwort

1

eval

$ eval "id=uid5 prog=/opt/bin/example arg=\"-D -t5 >/dev/null 1>&2\" info='fdhff fd'" 
$ echo $id 
uid5 
$ echo $prog 
/opt/bin/example 
$ echo $arg 
-D -t5 >/dev/null 1>&2 
$ echo $info 
fdhff fd 
+2

... mit dem großen Vorbehalt, dass Sie nicht "eval" Benutzer-bereitgestellten Code ... – DevSolar

+0

wenn es vom Benutzer geliefert wurde, dann könnte es angefordert werden, eine var zu einer Zeit –

4

Sieht aus wie Sie eval verwenden könnte die Shell analysieren Ihre Eingabestring zu lassen, aber wenn Sie nicht die Eingabe steuern kann (wenn es darum geht, aus einer unzuverlässigen Quelle) , das wird eine große Schwachstelle einführen (stellen Sie sich vor, dass ein Angreifer irgendwie -c "rm -rf /" an Ihr Programm übergibt).

Ein sicherer Weg wäre, zulässige Formen der Benutzereingabe explizit anzugeben.

Das Problem, das Sie mit Splitting auf Platz haben (mit cut), wenn der Raum zitiert wird, vermieden werden kann, wenn Sie gültige Felder (Inhalt, nicht Separator), zum Beispiel in GNU awk, geben Sie verwenden können FPAT:

$ params="id=uid5 prog=/opt/bin/example arg=\"-D -t5 >/dev/null 1>&2\" info='fdhff fd'" 
$ awk -v FPAT="[^=]+=(\"[^\"]*\"|'[^']*'|[^ ]*) *" '{for (i=1; i<=NF; i++) print $i}' <<<"$params" 
id=uid5 
prog=/opt/bin/example 
arg="-D -t5 >/dev/null 1>&2" 
info='fdhff fd' 

Gültige Felder in einer der folgenden Formen sein:

var="val with spaces" 
var='val with spaces' 
var=val_no_spaces 

Jetzt wit h Zuweisungen Split (eine pro Zeile, Newline unter der Annahme, in params nicht erlaubt ist), können Sie diese weiter verarbeiten, auch mit cut:

$ awk ... | cut -d $'\n' -f3 
arg="-D -t5 >/dev/null 1>&2"