Beim Schreiben von Code habe ich festgestellt, dass diese Zeile:
$ TZ="America/Los_Angeles" date; echo "$TZ"
Thu Dec 24 14:39:15 PST 2015
Gibt korrekt die tatsächliche Zeit in "Los Angeles" an und dass der Wert der Variablen TZ
nicht beibehalten wird. Alles wie erwartet.
Mit dieser Zeile, mit der ich bisher einige Formate erweitert habe und die im Wesentlichen dasselbe ausführt, bleibt jedoch der Wert von TZ erhalten:
TZ="America/Los_Angeles" eval date; echo "$TZ"
Thu Dec 24 14:41:34 PST 2015
America/Los_Angeles
Nach mehreren weiteren Tests stellte ich fest, dass dies nur in einigen Schalen geschieht. Es passiert in dash, ksh aber nicht in bash oder zsh.
Q's
Die Frage (n) sind:
- Warum bleibt der Wert von TZ in der vorliegenden Hülle erhalten?
- Wie könnte dies vermieden / kontrolliert werden (wenn möglich)?
Zusätzlich.
Ich habe Tests in mehreren Schalen mit diesen beiden Zeilen durchgeführt:
myTZ="America/Los_Angeles"
unset TZ; { TZ="$myTZ" date; } >/dev/null; echo -n " direct $TZ"
unset TZ; { TZ="$myTZ" eval date; } >/dev/null; echo " evaled $TZ"
Und das Ergebnis:
/bin/ash : direct evaled America/Los_Angeles
/bin/dash : direct evaled America/Los_Angeles
/bin/sh : direct evaled America/Los_Angeles
/bin/bash : direct evaled
/bin/ksh93 : direct evaled America/Los_Angeles
/bin/lksh : direct evaled America/Los_Angeles
/bin/mksh : direct evaled America/Los_Angeles
/bin/zsh : direct evaled
/bin/zsh4 : direct evaled
Der TZ-Wert wirkt sich auf die laufende Shell in allen Shells außer Bash und Zsh aus.
Es stellt sich heraus, dass es einen ganz bestimmten Grund für dieses Verhalten gibt.
Die Beschreibung dessen, was passiert, ist etwas länger.
Nur Aufgaben.
Eine Befehlszeile, die (nur) aus Zuweisungen besteht, legt die Variablen für diese Shell fest.
Der Wert der zugewiesenen Variablen bleibt erhalten.
Externer Befehl.
Zuweisungen vor einem externen Befehlssatz Variablen nur für diese Shell:
Und ich meine "extern" als jeden Befehl, der in PATH gesucht werden muss.
Dies gilt auch für normale integrierte Funktionen (wie z. B. CD):
Bis hierher ist alles so, wie es normalerweise erwartet wird.
Spezielle Einbauten.
Für spezielle integrierte Funktionen erfordert POSIX jedoch, dass die Werte für diese Shell festgelegt werden .
Ich benutze einen Aufruf, um
sh
anzunehmen, dasssh
es sich um eine POSIX-kompatible Shell handelt.Dies wird normalerweise nicht verwendet.
Dies bedeutet, dass Zuweisungen, die vor einer dieser Listen spezieller Einbauten platziert werden, die zugewiesenen Werte in der aktuellen laufenden Shell beibehalten müssen:
Dies geschieht, wenn eine Shell gemäß der POSIX-Spezifikation funktioniert.
Fazit:
Es ist möglich, Variablen für nur einen Befehl, einen beliebigen Befehl, festzulegen, indem sichergestellt wird, dass der Befehl nicht speziell integriert ist. Der Befehl
command
ist regelmäßig eingebaut. Es weist die Shell nur an, einen Befehl zu verwenden, keine Funktion. Diese Zeile funktioniert in allen Shells (außer ksh93):In diesem Fall werden die Variablen a und b für die Umgebung des Befehlsbefehls festgelegt und danach verworfen.
Stattdessen bleiben die zugewiesenen Werte erhalten (außer bash und zsh):
Beachten Sie, dass die Zuweisung nach der Auswertung in einfachen Anführungszeichen steht, um sie vor unerwünschten Erweiterungen zu schützen.
Also: Um Variablen in der Befehlsumgebung zu platzieren, verwenden Sie
command eval
:quelle