GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo canalizar comandos a cualquier terminal?

A menudo uso más de un terminal (o emulador de terminal) a la vez; y mientras que en X puedo copiar y pegar comandos, además de no ser muy práctico, obviamente no funciona en el TTY real. La primera idea que se me ocurre es algo parecido:

command > /dev/sometty

Desafortunadamente, el comando command se ejecuta antes está canalizado, y no hay trucos como echo `command` funcionará, sin importar cuántos caracteres bash raros ($ , ` , " , etc.) están ahí. Así que /dev/sometty simplemente recibe un mensaje de texto.

El problema es que, a veces, incluso vale la pena canalizar esos comandos en un archivo, hacerlo ejecutable, etc., o en breve:hacer un script y ejecutarlo desde la terminal adecuada. Pero eso es mucho trabajo. Estuve pensando en hacer un script para hacer estos archivos, para una instrucción:

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

haría algo como:

  1. enviar los comandos a, por ejemplo, /tmp/termpipe-20140208-153029-1.sh
  2. hacer que el archivo sea ejecutable
  3. ejecutar el archivo en el terminal apropiado
  4. eliminar el script cuando termine de ejecutarse

AFAIK, el problema está en 3. :esto no resuelve ningún problema, ya que necesitaría otro termpipe instancia para ejecutar la primera en el terminal apropiado. Y uno para ese. Y otra para eso, ad infinitum . Así que esto no puede funcionar. ¿O puede?…

La solución podría ser usar una canalización con nombre por terminal, y cuando cada una se inicia, un script le indicaría a la canalización que reenvíe cualquier cosa que reciba a la terminal y luego ejecutarla (como una especie de daemon ).

Creo que esto podría funcionar, pero no sé cómo configurar el script inicial. ¿Cómo puedo? ¿Cómo puedo decirle al FIFO que dé comandos canalizados para que se ejecute la terminal respectiva? No sé mucho de Bash, así que agradecería explicaciones completas.

Respuesta aceptada:

Después de esto, uno puede muy bien hacer que ese último plan suyo funcione. Para que el shell no procese el comando que se enviará, debe tener la forma de una cadena cuando llegue a la tubería (por lo tanto, echo "command" , no echo `command` ). Luego tiene que ser leído por un proceso en segundo plano (como un daemon , pero no necesariamente) iniciado en el terminal apropiado. Debe ser evaluado por el mismo proceso.

Pero es boiler-platey tener un script por tubería. Así que generalicemos haciendo un script como term-pipe-r.sh (no te olvides de chmod +x eso!):

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

Así que di que quieres /dev/tty3 para recibir comandos:solo ve allí, haz

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

Y para enviar comandos, desde cualquier terminal (incluso de sí mismo):

echo "command" > tty3pipe

o para ejecutar un archivo allí:

cat some-script.sh > tty3pipe

Tenga en cuenta que esta tubería ignora archivos como .bashrc , y los alias allí, como alias ls='ls --color' . Espero que esto ayude a alguien.

Relacionado:Linux – Arch linux wifi funciona manualmente, ¿cómo hacerlo automático?

Editar (nota:ventaja de no daemon ):

Arriba hablé de que el lector de tuberías no es un daemon necesariamente, pero de hecho, revisé las diferencias, y resulta que es mucho mejor ser un mero proceso en segundo plano en este caso. Porque de esta manera, cuando cierras la terminal, un EXIT señal (SIGHUP , SIGTERM , o lo que sea) también es recibido por el script, y luego se elimina la canalización (consulte la línea que comienza con trap en el script) automáticamente, evitando un proceso y un archivo inútiles (y tal vez otros si hubiera tal redireccionamiento a la tubería inútil).

Editar (automatización):

Aún así, es aburrido tener que ejecutar un script que (al menos yo) probablemente quiera la mayor parte del tiempo. Entonces, ¡automaticémoslo! Debería comenzar en cualquier terminal, y una cosa que todos leen es .bashrc . Además, apesta tener que usar ./term-pipe-r.sh . Entonces, uno puede hacer:

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)

Ahora, para ejecutarlo, solo necesitaría tpr tty3pipe & en /dev/tty3 cuando quieras. Pero, ¿por qué hacer eso cuando puede hacerlo automáticamente? Entonces esto debería agregarse a .bashrc . Pero espera:¿cómo sabrá el nombre de la tubería? Puede basar el nombre en el TTY (que se puede saber con el tty comando), usando REGEX simples en sed (y algunos trucos). Lo que debe agregar a ~/.bashrc será entonces:

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. Cómo usar los comandos del historial de Bash

  2. ¿Cómo canalizar la lista de comandos que se muestra en "tab Complete"?

  3. Cómo agotar el tiempo de espera de un grupo de comandos en Bash

  4. ¿Cómo limitar la velocidad de una tubería en Linux?

  5. ¿Cómo agrupar los comandos en un archivo preconfigurado de Debian?

Cómo mostrar imágenes en miniatura en la terminal

Cómo grabar todo lo que haces en la terminal

Cómo abrir una ventana de terminal de Linux

Cómo abrir un PDF en la terminal de Linux

¿Cómo usar Terminal en cPanel?

Cómo ejecutar varios comandos de Linux a la vez en la terminal de Linux