Gibt es eine Möglichkeit, stdout und stderr über Variablen umzuleiten, wie das Hinzufügen von Befehlsoptionen im Skript?
Zum Beispiel habe ich ein Skript:
#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
mkdir $OPT 123/123/123 $TEST
Ich kann sehen, dass OPT -p
ohne Probleme durch ersetzt wird und Bash interpretiert es als Option. Die Umleitung wird jedoch als Verzeichnisname interpretiert.
$ ./test.sh
+ TEST='>/dev/null 2>&1'
+ OPT='-p -v'
+ mkdir -p -v 123/123/123 '>/dev/null' '2>&1'
mkdir: created directory `123/123'
mkdir: created directory `123/123/123'
mkdir: created directory `>/dev'
mkdir: created directory `>/dev/null'
mkdir: created directory `2>&1'
Gibt es eine Möglichkeit, bash zu sagen, dass $ VAR eine Umleitung ist, keine Verzeichnisnamen.
PS. Vielleicht bin ich auf dem falschen Weg, aber ich möchte eine optionale ausführliche oder nicht ausführliche Ausgabe von meinem Skript machen. Aber ich brauche eine Ausgabe auch im nicht-ausführlichen Modus, daher kann ich nicht nur ganze stdout- und stderr-Befehle umleiten, sondern nur einige Befehle innerhalb meines Skripts.
Das "Wie" ist in anderen Antworten gut erklärt worden; Ich möchte das "Warum" ansprechen, dass der OP-Code nicht funktioniert.
Das Wichtigste ist, dass Ausgabeumleitungen vor der Variablenerweiterung markiert werden. Umleitungen sind tatsächlich durchgeführt , nachdem variable Expansion (daher , warum Sie die Ausgabe auf einen Dateinamen umleiten können , die in einer Variablen gespeichert ist), aber die Schale identifiziert die Umleitungen für die spätere Verarbeitung vor Variablen erweitert.
Mit anderen Worten, sobald Variablen erweitert sind, ist es "zu spät", ein Umleitungszeichen (
<
oder>
usw.) zu berücksichtigen, da die Shell bereits identifiziert hat, welche Teile der Befehlszeichenfolge als Umleitungen behandelt werden sollen.Weitere Informationen finden Sie in den Schritten 1 und 3 unter:
quelle
Es wird nicht als "Verzeichnisname" interpretiert, sondern
>
in Anführungszeichen gesetzt, sodass es wörtlich behandelt wird (genauer gesagt, Sie senden die Zeichenfolge>dev/null 2>&1
. Sie können dies nur umgehen, indem Sieeval
eine neue Shell verwenden oder erstellen.Gehen Sie stattdessen wie folgt vor, um Ihr in Ihrer Frage angesprochenes "ausführliches" Problem zu lösen:
quelle
Sie haben viele Leerzeichen in Ihren Variablen, die nicht richtig ausgewertet werden. Sie werden es verwenden wollen, um
eval
das einzurichten.Auf diese Weise kann $ OPT mit $ TEST in zwei Argumente (
-p
und-v
) anstelle von einem (-p -v
) und demselben Argument aufgeteilt werden . Auch zur Verwendung geändert,/dev/null
da es sehr unwahrscheinlich ist, dass Sie eindev
Verzeichnis im aktuellen Verzeichnis haben.quelle
Die Antwort von enzotib verwendet eine gute Dateideskriptormagie, aber eine einfachere Lösung wäre, nur
eval
die Zeile zu verwenden (was jedoch den Prozessaufwand erhöht):quelle