Cómo enviar un comando de terminal a un terminal TTY

8

Estoy buscando una manera de enviar un comando ejecutado a un terminal TTY. Por ejemplo, digamos que abro el terminal gnome y en la ventana que escribo sudo aptitude update && sudo aptitude upgrade.

¿Cómo puedo enviar esto a un terminal TTY en lugar de trabajar con él en el entorno TTY7 GUI?

Luis Alvarado
fuente

Respuestas:

7

Recomendaría no hacerlo directamente, pero use un multiplexor de terminal, como tmux, como un intermedio.

En el terminal que debería recibir el comando start tmux con un identificador:

tmux new-session -s MYSES

Envíale comandos con:

tmux send-keys -t MYSES "sudo aptitude update && sudo aptitude upgrade"$'\n'
Thor
fuente
si usa byobu, ¡esto también funciona! Y puede soltar -t MYSES si resulta que se está ejecutando una sesión que ya no conoce su nombre. Thnx!
ExploWare
10

Este es un programa que ayudará a:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>

void print_help(char *prog_name) {
        printf("Usage: %s [-n] DEVNAME COMMAND\n", prog_name);
        printf("Usage: '-n' is an optional argument if you want to push a new line at the end of the text\n");
        printf("Usage: Will require 'sudo' to run if the executable is not setuid root\n");
        exit(1);
}

int main (int argc, char *argv[]) {
    char *cmd, *nl = "\n";
    int i, fd;
    int devno, commandno, newline;
    int mem_len;
    devno = 1; commandno = 2; newline = 0;
    if (argc < 3) {
        print_help(argv[0]);
    }
    if (argc > 3 && argv[1][0] == '-' && argv[1][1] == 'n') {
        devno = 2; commandno = 3; newline=1;
    } else if (argc > 3 && argv[1][0] == '-' && argv[1][1] != 'n') {
        printf("Invalid Option\n");
        print_help(argv[0]);
    }
    fd = open(argv[devno],O_RDWR);
    if(fd == -1) {
        perror("open DEVICE");
        exit(1);
    }
    mem_len = 0;
    for ( i = commandno; i < argc; i++ ) {
        mem_len += strlen(argv[i]) + 2;
        if ( i > commandno ) {
            cmd = (char *)realloc((void *)cmd, mem_len);
        } else { //i == commandno
            cmd = (char *)malloc(mem_len);
        }

        strcat(cmd, argv[i]);
        strcat(cmd, " ");
    }
  if (newline == 0)
        usleep(225000);
    for (i = 0; cmd[i]; i++)
        ioctl (fd, TIOCSTI, cmd+i);
    if (newline == 1)
        ioctl (fd, TIOCSTI, nl);
    close(fd);
    free((void *)cmd);
    exit (0);
}

Copie el código anterior en algún archivo C (por ejemplo, ttyecho.c). Ejecute el siguiente comando en el directorio en el que ha creado el archivo C para compilar el código.

make ttyecho

Copie este archivo en el directorio bin en su Directorio de inicio. Cree el directorio si no existe. Es una buena práctica mantener todos los archivos binarios / ejecutables personalizados en este directorio bin.

Inicie otro terminal o cambie a cualquier otro terminal abierto que desee controlar y ejecute el comando tty. Puede ver una salida de muestra a continuación.

@~$ tty

/ dev / pts / 5

Ahora para ejecutar un comando en / dev / pts / 5 , ejecute el siguiente comando en el terminal de control / original.

sudo ttyecho -n /dev/pts/5 ls

Verá que el comando ls se ejecuta en / dev / pts / 5 . La opción -n hace que ttyecho envíe una nueva línea después del comando, para que el comando se ejecute y no solo se inserte. Esta utilidad se puede utilizar para enviar datos a otros terminales. Por ejemplo, puede abrir vim en / dev / pts / 5 y luego ejecutar el siguiente comando en el terminal de control para hacer que vim salga en / dev / pts / 5 .

sudo ttyecho -n /dev/pts/5 :q

Para evitar usar sudo todo el tiempo, de modo que el comando sea fácilmente programable, cambie los propietarios / permisos de este ejecutable usando los siguientes comandos.

sudo chown root:root ttyecho
sudo chmod u+s ttyecho

Nota: configurar el bit setuid puede convertirse en un riesgo de seguridad.

Fuente: http://www.humbug.in/2010/utility-to-send-commands-or-data-to-other-terminals-ttypts/

Eyal Levin
fuente