Ich habe die letzte Stunde oder so damit verbracht, ein ziemlich einfaches Bash-Skript zu schreiben, und ich kam mir noch nie so dumm vor.
Ich habe also eine Liste von Zeichenfolgen (die Paketauswahlspezifikationen für einen Paketmanager sind, falls das wichtig ist), die möglicherweise Sternchen enthalten. Ich muss eine Befehlszeile erstellen, die diese Sternchen beibehält, und dann ein Programm aufrufen. Hier ist mein naiver Versuch:
xs="foo/bar */*"
xs_cmd=""
for x in $xs; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
Ich brauche den echo
Anruf, der gleichwertig ist mit
echo -0 foo/bar -0 '*/*'
welche Ausgaben -0 foo/bar -0 */*
.
PS: In Wirklichkeit ist die erste Zeile etwas komplexer: xs="$some foo/bar */* $(get_others)"
.
Wenn Sie dieses Skript in einem Verzeichnis ausführen, das enthält a/b
, erhalten Sie -0 foo/bar -0 a/b
stattdessen.
Wenn ich die letzte Zeile ändere in
echo "$xs_cmd" # note the quotes
Ich bekomme -0 foo/bar -0 a/b
und, erstens, das ist nicht, was ich will, da ich jetzt echo
mit einemeinzelArgument, und darüber hinaus sagt mir das, dass die Erweiterung früher stattfindet, wahrscheinlich in der for
Schleife.
Aber ich kann die Zeile nicht ändern, for
weil
for x in "$xs"; do # note the quotes
führt dazu, dass die Schleife nur einmal wiederholt wird: -0 foo/bar */*
(es gibt ein einzelnes -0
), daher ist das Hinzufügen dieser Anführungszeichen definitiv keine Option.
Wenn ich jetzt zum ursprünglichen Skript zurückkehre und die erste Zeile ersetze durch
xs="foo/bar '*/*'" # note additional single quotes
Ich verstehe -0 foo/bar -0 '*/*'
(einfache Anführungszeichen sollten da nicht stehen).
Es scheint, als hätte ich jede Kombination aus Anführungszeichen und Backslash-Escapezeichen für Sternchen ausprobiert und ich habe buchstäblich keine Ahnung, was ich jetzt tun soll.
Antwort1
Ich habe Ihr Originalskript verwendet, aber mit einfachen Anführungszeichen (nur) in der ersten Zeile, und es hat, glaube ich, so funktioniert, wie Sie es möchten ( -0
vor jedem Dateipfad): -
xs='foo/bar */*'
xs_cmd=""
for x in $xs; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
Wenn in einem der Dateipfade eingebettete Leerzeichen vorhanden sind, treten bei der Verwendung wahrscheinlich Probleme auf. Ändern Sie in diesem Fall den Befehl in der Schleife wie folgt:
xs_cmd="$xs_cmd -0 \"$x\" "
Antwort2
Je nachdem, was Sie erreichen möchten, müssen Sie entweder Folgendes zitieren */*
:
xs="foo/bar '*/*'" #!
xs_cmd=""
for x in $xs ; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
eval echo $xs_cmd
eval "echo $xs_cmd"
oder Arrays verwenden oder beides:
xs=("foo/bar" "*/*") #!
xs_cmd=""
for x in "${xs[@]}"; do
xs_cmd="$xs_cmd -0 '$x' " #!
done
echo "$xs_cmd"
eval "echo $xs_cmd"