Ich verwende oft mehr als ein Terminal (oder Terminal-Emulator) gleichzeitig; und während ich in X Befehle kopieren und einfügen kann, funktioniert es offensichtlich nicht auf dem echten TTY, abgesehen davon, dass es nicht sehr praktisch ist. Die erste Idee, die mir einfällt, ist etwas ähnliches:
command > /dev/sometty
Leider ist der command
vorher ausgeführt wird es wird geleitet und es gibt keine Tricks wie echo `command`
funktioniert, egal wie viele seltsame Bash-Zeichen ($
, `
, "
, usw.) sind vorhanden. Also /dev/sometty
erhält einfach etwas Text.
Das Problem ist, dass es sich manchmal sogar lohnt, diese Befehle in eine Datei zu leiten, sie ausführbar zu machen usw., oder kurz:ein Skript zu erstellen und es vom entsprechenden Terminal aus auszuführen. Aber das ist viel Arbeit. Ich habe darüber nachgedacht, ein Skript zu erstellen, um diese Dateien zu erstellen, für eine Anweisung:
termpipe -e "command1\ncommand2\"command 1 argument\\n(s)\"" -t /dev/sometty
es würde so etwas tun:
- leiten Sie die Befehle beispielsweise an
/tmp/termpipe-20140208-153029-1.sh
weiter - Datei ausführbar machen
- Führen Sie die Datei im entsprechenden Terminal aus
- Löschen Sie das Skript, wenn es ausgeführt wird
AFAIK, das Problem liegt in 3. :Dies löst kein Problem, da ich eine weitere termpipe
benötigen würde Instanz, um die erste auf dem entsprechenden Terminal auszuführen. Und eine für diese. Und dafür noch eins, ad infinitum . Das kann also nicht funktionieren. Oder kann es?…
Die Lösung könnte darin bestehen, eine benannte Pipe pro Terminal zu verwenden, und wenn jedes gestartet wird, würde ein Skript die Pipe anweisen, alles, was sie empfängt, an das Terminal weiterzuleiten und es dann auszuführen (wie eine Art Daemon ).
Ich denke, das könnte funktionieren, aber ich weiß nicht, wie ich das anfängliche Skript einrichten soll. Wie kann ich? Wie kann ich dem FIFO sagen, dass es Befehle für die Ausführung des jeweiligen Terminals geben soll? Ich kenne nicht viel Bash, daher würde ich mich über vollständige Erklärungen freuen.
Akzeptierte Antwort:
Danach kann man sehr gut diesen letzten Plan Ihrer Arbeit machen. Damit der zu sendende Befehl nicht von der Shell verarbeitet wird, muss er in Form eines Strings die Pipe erreichen (also echo "command"
, nicht echo `command`
). Dann muss es von einem Hintergrundprozess (ähnlich einem Daemon) gelesen werden , aber nicht notwendigerweise) im entsprechenden Terminal gestartet. Es sollte nach demselben Verfahren evaluiert werden.
Aber es ist Boiler-platey um ein Skript pro Pipe zu haben. Lassen Sie uns also das Erstellen eines Skripts als term-pipe-r.sh
verallgemeinern (vergessen Sie nicht chmod +x
es!):
#!/bin/bash
pipe=$1 # the pipe name is the first argument
trap 'rm -f "$pipe"' EXIT # ignore exit and delete messages until the end
if [[ ! -p $pipe ]]; then # if the pipe doesn't exist, create it
mkfifo $pipe
fi
while true # cycle eternally..
do
if read line <$ pipe; then
if [[ "$line" == 'close the term-pipe pipe' ]]; then
break
# if the pipe closing message is received, break the while cycle
fi
echo # a line break should be used because of the prompt
eval $line # run the line: as this script should be started
fi # in the target terminal,
done # the line will be run there.
echo "<pipe closing message>" # custom message on the end of the script
Sagen Sie also, Sie wollen /dev/tty3
um Befehle zu erhalten:einfach dorthin gehen, tun
./term-pipe-r.sh tty3pipe & # $1 will be tty3pipe (in a new process)
Und um Befehle von jedem Terminal zu senden (sogar von sich selbst):
echo "command" > tty3pipe
oder um dort eine Datei auszuführen:
cat some-script.sh > tty3pipe
Beachten Sie, dass dieses Piping Dateien wie .bashrc
ignoriert , und die darin enthaltenen Aliase, wie alias ls='ls --color'
. Hoffe, das hilft jemandem da draußen.
Bearbeiten (Hinweis – Vorteil von Nicht-Daemon ):
Oben habe ich darüber gesprochen, dass der Pipe-Reader kein Daemon ist notwendig, aber tatsächlich habe ich die Unterschiede überprüft, und es stellt sich heraus, dass es in diesem Fall viel besser ist, ein bloßer Hintergrundprozess zu sein. Denn so wird beim Schließen des Terminals ein EXIT
Signal (SIGHUP
, SIGTERM
, oder was auch immer) wird ebenfalls vom Skript empfangen, und die Pipe wird dann gelöscht (siehe die Zeile, die mit trap
beginnt im Skript) automatisch, wodurch ein nutzloser Prozess und eine nutzlose Datei vermieden werden (und vielleicht andere, wenn es solche gibt, die auf die nutzlose Pipe umgeleitet werden).
Bearbeiten (Automatisierung):
Trotzdem ist es langweilig, ein Skript ausführen zu müssen, das Sie (zumindest ich) wahrscheinlich die meiste Zeit wollen. Also lasst es uns automatisieren! Es sollte in jedem Terminal starten, und eine Sache, die alle lesen, ist .bashrc
. Außerdem ist es scheiße, ./term-pipe-r.sh
verwenden zu müssen . Man kann also Folgendes tun:
cd /bin # go to /bin, where Bash gets command names
ln -s /directory/of/term-pipe-r.sh tpr # call it tpr (terminal pipe reader)
Um es jetzt auszuführen, brauchen Sie nur noch tpr tty3pipe &
in /dev/tty3
wann immer Sie möchten. Aber warum sollte man das tun, wenn man es auch automatisch machen lassen kann? Dies sollte also zu .bashrc
hinzugefügt werden . Aber warten Sie:Wie wird es den Pipe-Namen kennen? Es kann den Namen auf dem TTY basieren (das mit dem tty
bekannt ist Befehl), mit einfachen REGEX’s in sed
(und einige Tricks). Was Sie zu ~/.bashrc
hinzufügen sollten wird dann:
pipe="$(sed 's/\/dev\///' <<< `tty` | sed 's/\///')pipe"
# ^^^- take out '/dev/' and other '/', add 'pipe'
tpr $pipe & # start our script with the appropriate pipe name