GNU/Linux >> Znalost Linux >  >> Linux

Jak převést příkazy do libovolného terminálu?

Často používám více než jeden terminál (nebo emulátor terminálu) najednou; a zatímco v X mohu kopírovat a vkládat příkazy, kromě toho, že to není příliš praktické, zjevně to nefunguje na skutečném TTY. První nápad, který mě napadá, je něco podobného:

command > /dev/sometty

Bohužel, command je spuštěna před je to rourou a žádné triky jako echo `command` bude fungovat bez ohledu na to, kolik podivných bash znaků ($ , ` , " atd.) jsou tam. Takže /dev/sometty prostě dostane nějaký text.

Problém je v tom, že někdy dokonce stojí za to, abych tyto příkazy vložil do souboru, udělal jej spustitelným atd., nebo krátce:vytvořil skript a spustil jej z příslušného terminálu. Ale to je hodně práce. Přemýšlel jsem o vytvoření skriptu pro vytvoření těchto souborů, pro instrukci:

termpipe -e "command1\ncommand2\"command 1 argument\\n(s)\"" -t /dev/sometty 

udělalo by to něco jako:

  1. přepojte příkazy do, řekněme, /tmp/termpipe-20140208-153029-1.sh
  2. udělejte soubor spustitelným
  3. spusťte soubor v příslušném terminálu
  4. po dokončení skript smažte

AFAIK, problém je v 3. :to neřeší žádný problém, protože bych potřeboval další termpipe instanci spustit první na příslušném terminálu. A jeden pro toho. A další na to, ad infinitum . Takže to nemůže fungovat. Nebo může?…

Řešením by mohlo být použití pojmenovaného kanálu na terminál, a když se každý spustí, skript řekne kanálu, aby přeposlal vše, co obdrží, na terminál a pak to provedl (jako jakýsi démon ).

Myslím, že by to mohlo fungovat, ale nevím, jak nastavit počáteční skript. Jak mohu? Jak mohu říct FIFO, aby zadávalo pipetované příkazy pro spuštění příslušného terminálu? Bashe moc neznám, takže bych ocenil úplné vysvětlení.

Přijatá odpověď:

Po tomto můžete velmi dobře uskutečnit váš poslední plán. Aby příkaz, který má být odeslán, nebyl shellem zpracován, musí být ve formě řetězce, když dosáhne roury (tedy echo "command" , nikoli echo `command` ). Poté jej musí přečíst proces na pozadí (podobně jako démon , ale ne nutně) spuštěna v příslušném terminálu. Mělo by být vyhodnoceno stejným procesem.

Ale je to kotel-ploché mít skript na potrubí. Pojďme tedy zobecnit vytvoření skriptu jako term-pipe-r.sh (nezapomeňte chmod +x to!):

#!/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

Řekněme, že chcete /dev/tty3 pro příjem příkazů:prostě jděte tam, udělejte

./term-pipe-r.sh tty3pipe &     # $1 will be tty3pipe (in a new process)

A k odesílání příkazů z jakéhokoli terminálu (i od sebe samého):

echo "command" > tty3pipe

nebo tam spustit soubor:

cat some-script.sh > tty3pipe

Všimněte si, že toto potrubí ignoruje soubory jako .bashrc a aliasy v nich obsažené, například alias ls='ls --color' . Doufám, že to někomu pomůže.

Související:Linux – Arch linux wifi funguje ručně, jak to udělat automaticky?

Upravit (poznámka – výhoda nedémona ):

Výše jsem mluvil o tom, že čtečka rour není démon nutně, ale ve skutečnosti jsem zkontroloval rozdíly a ukázalo se, že v tomto případě je mnohem lepší být pouhým procesem na pozadí. Protože tímto způsobem, když zavřete terminál, EXIT signál (SIGHUP , SIGTERM , nebo cokoli jiného) je také přijato skriptem a roura je poté smazána (viz řádek začínající trap ve skriptu) automaticky, čímž se vyhnete zbytečnému procesu a souboru (a možná i dalším, pokud by takové přesměrování do zbytečné roury bylo).

Upravit (automatizace):

Přesto je nudné spouštět skript, který (alespoň já) pravděpodobně většinu času chcete. Tak to zautomatizujme! Měl by začínat v libovolném terminálu a jedna věc, kterou všechny čtou, je .bashrc . Navíc je otravné používat ./term-pipe-r.sh . Takže, jeden může udělat:

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)

Nyní k jeho spuštění budete potřebovat pouze tpr tty3pipe & v /dev/tty3 kdykoli budete chtít. Ale proč to dělat, když to můžete nechat udělat automaticky? Toto by tedy mělo být přidáno do .bashrc . Ale počkat:jak to bude znát název potrubí? Název může založit na TTY (které lze znát pomocí tty příkaz), pomocí jednoduchých REGEX v sed (a pár triků). Co byste měli přidat do ~/.bashrc pak bude:

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. Jak používat příkazy historie Bash

  2. Jak zkontrolovat HZ v terminálu?

  3. Jak spustit skript .sh z libovolné cesty v terminálu?

  1. Jak poslat Stdout do více příkazů?

  2. Jak hodnotit-limitovat potrubí pod linuxem?

  3. Jak propojím příkazy v souboru s přednastavením debianu?

  1. Jak spouštět příkazy Linuxu na pozadí

  2. Jak vytvořit kanál se seznamem příkazů zobrazených jako „karta dokončena“?

  3. Jak časový limit skupiny příkazů v Bash