In einer bestimmten Shell würde ich normalerweise eine Variable oder Variablen festlegen und dann einen Befehl ausführen. Kürzlich habe ich das Konzept kennengelernt, einem Befehl eine Variablendefinition voranzustellen:
FOO=bar somecommand someargs
Das funktioniert ... irgendwie. Es funktioniert nicht, wenn Sie eine LC_ * -Variable ändern (was den Befehl zu beeinflussen scheint, aber nicht seine Argumente, z. B. '[az]' - Zeichenbereiche) oder wenn Sie die Ausgabe folgendermaßen an einen anderen Befehl weiterleiten:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
Ich kann somecommand2 auch mit "FOO = bar" voranstellen, was funktioniert, aber unerwünschte Duplikate hinzufügt, und es hilft nicht bei Argumenten, die abhängig von der Variablen interpretiert werden (zum Beispiel '[az]').
Was ist also ein guter Weg, dies in einer einzigen Zeile zu tun?
Ich denke etwas in der Größenordnung von:
FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work
Ich habe viele gute Antworten bekommen! Das Ziel ist es, dies einzeilig zu halten, vorzugsweise ohne "Export" zu verwenden. Die Methode mit einem Aufruf von Bash war insgesamt am besten, obwohl die in Klammern gesetzte Version mit "Export" etwas kompakter war. Interessant ist auch die Methode, die Umleitung anstelle einer Pipe zu verwenden.
quelle
(T=$(date) echo $T)
wird funktionierenAntworten:
quelle
somecommand
als sudo ausführen müssen, sudo das-E
Flag übergeben müssen, um durch Variablen zu übergeben. Weil Variablen Schwachstellen verursachen können. stackoverflow.com/a/8633575/1695680FOO_X=foox bash -c 'echo $FOO_X'
wie erwartet, schlägt jedoch bei bestimmten Variablennamen fehl:DYLD_X=foox bash -c 'echo $DYLD_X'
Echos leer. beide arbeiten miteval
anstelle vonbash -c
Wie wäre es mit dem Exportieren der Variablen, aber nur innerhalb der Subshell?:
Keith hat einen Punkt, um die Befehle bedingungslos auszuführen, tun Sie dies:
quelle
;
eher verwenden als&&
; Es gibt keinen Wegexport FOO=bar
, der scheitern wird.&&
den linken Befehl aus und führt den rechten Befehl nur aus, wenn der linke Befehl erfolgreich war.;
führt beide Befehle bedingungslos aus. Das Windows-Batch (cmd.exe
) -Äquivalent von;
ist&
.(FOO=XXX ; echo FOO=$FOO) ; echo FOO=$FOO
ErträgeFOO=XXX\nFOO=\n
.source
(aka.
) in diesem Fall verwenden? Außerdem sollten die Backticks heutzutage nicht mehr verwendet werden, und dies ist einer der Gründe, warum die Verwendung$(command)
waaaaay sicherer ist.bash
aber etwas anderes sein könnte, z. B.dash
), und ich habe keine Probleme, wenn ich Anführungszeichen verwenden muss innerhalb des Befehls args (someargs
).Sie können auch verwenden
eval
:Da diese Antwort mit
eval
nicht jedem zu gefallen scheint, lassen Sie mich etwas klarstellen: Wenn sie wie geschrieben mit den einfachen Anführungszeichen verwendet wird , ist sie absolut sicher. Es ist gut, da es weder einen externen Prozess startet (wie die akzeptierte Antwort) noch die Befehle in einer zusätzlichen Unterschale ausführt (wie die andere Antwort).Da wir ein paar regelmäßige Ansichten erhalten, ist es wahrscheinlich gut, eine Alternative zu geben
eval
, die allen gefällt und alle Vorteile (und vielleicht sogar noch mehr!) Dieses schnelleneval
„Tricks“ bietet . Verwenden Sie einfach eine Funktion! Definieren Sie eine Funktion mit all Ihren Befehlen:und führen Sie es mit Ihren Umgebungsvariablen wie folgt aus:
quelle
eval
.eval
ist böse, ohne zu verstehen, worum es böse isteval
. Und vielleicht verstehen Sie diese Antwort doch nicht wirklich (und daran ist wirklich nichts auszusetzen). Auf der gleichen Ebene: Würden Sie sagen, dassls
das schlechtfor file in $(ls)
ist, weil es schlecht ist? (und ja, Sie haben die akzeptierte Antwort nicht abgelehnt und auch keinen Kommentar hinterlassen). SO ist manchmal so ein seltsamer und absurder Ort.eval
ist böse, ohne zu verstehen, worum es böse isteval
, dann beziehe ich mich auf Ihren Satz: Dieser Antwort fehlen alle Warnungen und Erklärungen, die erforderlich sind, wenn Sie darüber sprecheneval
.eval
ist nicht schlecht oder gefährlich; nicht mehr alsbash -c
.eval
. In der Antwort, sofern die Argumente in einfachen Anführungszeichen stehen, um vor variabler Erweiterung zu schützen, sehe ich kein Problem mit der Antwort.eval
Ist ein Sicherheitsproblem im Allgemeinen (wie,bash -c
aber weniger offensichtlich), daher sollten die Gefahren in einer Antwort erwähnt werden, in der seine Verwendung vorgeschlagen wird. Unvorsichtige Benutzer können die Antwort (FOO=bar eval …
) nehmen und auf ihre Situation anwenden, so dass Probleme auftreten. Aber für den Antwortenden war es offensichtlich wichtiger herauszufinden, ob ich seine und / oder andere Antworten abgelehnt habe, als etwas zu verbessern. Wie ich bereits schrieb, sollte Fairness nicht das Hauptanliegen sein. Es ist auch unerheblich , nicht schlechter zu sein als jede andere gegebene Antwort.Verwenden
env
.Zum Beispiel,
env FOO=BAR command
. Beachten Sie, dass die Umgebungsvariablen nachcommand
Abschluss der Ausführung wieder hergestellt / unverändert bleiben .Seien Sie nur vorsichtig, wenn eine Shell-Substitution stattfindet. Wenn Sie also
$FOO
explizit auf dieselbe Befehlszeile verweisen möchten , müssen Sie diese möglicherweise maskieren, damit Ihr Shell-Interpreter die Substitution nicht ausführt, bevor sie ausgeführt wirdenv
.quelle
Verwenden Sie ein Shell-Skript:
quelle
export
; Andernfalls handelt$FOO
es sich um eine Shell-Variable, nicht um eine Umgebungsvariable, und daher fürsomecommand
oder nicht sichtbarsomecommand2
.