Wenn Sie eine Befehlsliste umleiten, die eine Exec-Umleitung enthält, scheint das exec> / dev / null danach nicht mehr angewendet zu werden, wie zum Beispiel mit:
{ exec >/dev/null; } >/dev/null; echo "Hi"
"Hi" wird gedruckt.
Ich hatte den Eindruck, dass die {}
Befehlsliste nur dann als Subshell betrachtet wird, wenn sie Teil einer Pipeline ist. Daher sollte die Befehlsliste exec >/dev/null
in meiner Vorstellung immer noch in der aktuellen Shell-Umgebung angewendet werden.
Nun, wenn Sie es ändern:
{ exec >/dev/null; } 2>/dev/null; echo "Hi"
es erfolgt keine erwartete Ausgabe; Dateideskriptor 1 zeigt auch für zukünftige Befehle auf / dev / null. Dies wird durch erneutes Ausführen gezeigt:
{ exec >/dev/null; } >/dev/null; echo "Hi"
das wird keine Ausgabe geben.
Ich habe versucht, ein Skript zu erstellen und es zu zeichnen, bin mir aber immer noch nicht sicher, was genau hier passiert.
Was passiert an jedem Punkt in diesem Skript mit dem STDOUT-Dateideskriptor?
BEARBEITEN: Hinzufügen meiner Strace-Ausgabe:
read(255, "#!/usr/bin/env bash\n{ exec 1>/de"..., 65) = 65
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD) = 0
fcntl(1, F_DUPFD, 10) = 10
fcntl(1, F_GETFD) = 0
fcntl(10, F_SETFD, FD_CLOEXEC) = 0
dup2(3, 1) = 1
close(3) = 0
close(10) = 0
open("/dev/null", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
fcntl(1, F_GETFD) = 0
fcntl(1, F_DUPFD, 10) = 10
fcntl(1, F_GETFD) = 0
fcntl(10, F_SETFD, FD_CLOEXEC) = 0
dup2(3, 1) = 1
close(3) = 0
dup2(10, 1) = 1
fcntl(10, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(10) = 0
fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, TCGETS, 0x7ffee027ef90) = -1 ENOTTY (Inappropriate ioctl for device)
write(1, "hi\n", 3) = 3
;
danach }
, der die Bedeutung von ändert, > /dev/null
um schließlich nicht auf die Verbundliste anzuwenden {}
.
close(10)
. Können Sie auch Ihren gesamten Skriptinhalt posten, auf den Sie gerade zugegangen sind?