GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie leitet man Befehle an ein beliebiges Terminal weiter?

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:

  1. leiten Sie die Befehle beispielsweise an /tmp/termpipe-20140208-153029-1.sh weiter
  2. Datei ausführbar machen
  3. Führen Sie die Datei im entsprechenden Terminal aus
  4. 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.

Verwandte:Linux – Arch Linux WLAN funktioniert manuell, wie macht man es automatisch?

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

Linux
  1. So verwenden Sie Bash-Verlaufsbefehle

  2. Wie kann ich die Liste der angezeigten Befehle von „Tab Complete“ weiterleiten?

  3. Wie überprüfe ich HZ im Terminal?

  4. Wie führe ich ein .sh-Skript von einem beliebigen Pfad in einem Terminal aus?

  5. Wie leite ich Befehle in einer Debian-Preseed-Datei zusammen?

So zeigen Sie Miniaturbilder im Terminal an

So zeichnen Sie alles auf, was Sie im Terminal tun

So öffnen Sie ein Linux-Terminalfenster

So öffnen Sie eine PDF-Datei im Linux-Terminal

Wie verwende ich das Terminal in cPanel?

So führen Sie mehrere Linux-Befehle gleichzeitig im Linux-Terminal aus