¿Cómo ejecuto el mismo comando de Linux en más de una pestaña / shell simultáneamente?


33

¿Hay alguna herramienta / comando en Linux que pueda usar para ejecutar un comando en más de una pestaña simultáneamente? Quiero ejecutar el mismo comando: ./myprog argument1 argument2simultáneamente en más de un shell para verificar si los mutexes funcionan bien en un programa enhebrado. Quiero poder aumentar el número de instancias de este programa para poner mi código bajo tensión más adelante.

Estoy buscando algo como lo que hace la pared. Puedo pensar en usar tty's, pero eso parece mucho dolor si tengo que escalar esto a muchos más proyectiles.


1
"Cada vez que te encuentres haciendo una tarea repetitiva que involucra una computadora, automatízala" - yo . Creo que puede estar haciendo un mal servicio al usar múltiples pestañas de terminal para la prueba de carga porque tendría que verlas todas, lo cual es tedioso. Es mejor tener un programa que genere myproginstancias secundarias y agregue su salida para usted.
msw

1
¿El subprocesamiento múltiple normal no tendrá un mutex entre procesos ...?
Aaron D. Marasco el

@msw: Sí, pero ¿qué pasaría si quisiera ver lo que vería el usuario final cuando ejecutara el mismo comando desde su terminal y cuando escalara eso para decir 100, qué verían en su pantalla? ¿No es eso algo válido para determinar?
Arpith

@ AaronD.Marasco: Quiero verificar las mutexes que he puesto, en el espacio del usuario.
Arpith

Así que ejecute 99 instancias bajo un supervisor y ejecute una centésima en una terminal. Admito que podrías ver 100 terminales simultáneamente, si es así, estoy impresionado.
msw

Respuestas:


46

Como mavillan ya sugirió, solo use terminador . Permite visualizar muchos terminales de forma en mosaico. Al habilitar la función de transmisión, puede ingresar el mismo comando simultáneamente en cada terminal.

Aquí hay un ejemplo con el comando de fecha transmitido a una cuadrícula de 32 terminales.

terminatorx32


3
¡Maldita sea, esto es increíble!
Afr

¿Cómo puedo abrir fácilmente 32 terminales?
Annan

66
@Annan Terminator admite diseños personalizados, eche un vistazo a unix.stackexchange.com/a/168445/2594 y askubuntu.com/a/178242/18306
jlliagre el

11

tmux tiene esta capacidad. (junto con muchas otras capacidades útiles en la misma línea)

Se puede hacer a través de:

:setw synchronize-panes on

¿podría describir brevemente cómo tmux hace eso o pegar un enlace? ¡Gracias!
eli

1
: setw sincronizar paneles en
Michael Martinez

9

Multixterm

Otra herramienta para agregar a la lista es una llamada multixterm. Utiliza xtermterminales. Puedes invocarlo así:

$ multixterm

Y una vez arriba, se te presentará una GUI.

                                                         ss de gui

Luego puede comenzar a girar xtermventanas haciendo clic en el new xtermbotón. Aquí, por ejemplo, he invocado 2. Si luego haces clic en la ventana principal, puedes comenzar a escribir comandos en ambas ventanas simultáneamente:

   ss de xtems

teclado

Parece que solo está disponible en Ubuntu, se parece a multixterm.

extracto

El propósito de la transmisión por teclado es permitirle enviar pulsaciones de teclas a múltiples ventanas X a la vez. Esto le permite, por ejemplo, controlar una serie de terminales conectadas a hosts diferentes pero similares para fines de administración masiva.

También puede seleccionar no terminales. Si se le ocurre un uso razonable de esta habilidad, me interesaría saberlo.

El programa puede seleccionar ventanas para enviar ya sea haciendo coincidir sus títulos (usando una subcadena) o haciendo clic en ellos (en un método similar a la función de captura de pantalla de GIMP).

El programa también presenta la capacidad de generar múltiples instancias de gnome-terminal ejecutando un solo comando en múltiples argumentos (por ejemplo, ejecutando 'ssh' en varios hosts). Los terminales gnome se invocan con el perfil 'keyboardcast' si existe (por lo tanto, por ejemplo, el tamaño de la fuente puede ser menor).


cuidadores! Nota tomada
runlevel0

Parece que el teclado está roto, lo cual es decepcionante.
RJ


8

Puedes hacer algo como:

max_processes=20
for ((i=0; i<$max_processes; i++))
do 
    /path/to/myprog arg1 arg2 > /tmp/myprog.${i}.log &
done

O si el resultado de cada comando es relevante durante la ejecución, puede configurar la pantalla.

vi ~/.screenrc
screen -t inst1    1 /path/to/myprog arg1 arg2
screen -t inst2    2 /path/to/myprog arg1 arg2
screen -t inst3    3 /path/to/myprog arg1 arg2
screen -t inst4    4 /path/to/myprog arg1 arg2

La pantalla requiere más trabajo manual.


¿Podría ampliar más en la solución de pantalla? Más en línea con lo que quiero ...
Arpith

¿Por qué no solo tail -fel archivo de registro en lugar de configurar un centenar de pantallas?
Lie Ryan

@Arpith la pantalla genera varios terminales en uno solo. Si desea verlos todos en "tiempo real", puede usar la pantalla. Aunque personalmente iría con archivos de registro, puede configurar su programa para enviar un mensaje o realmente tener su propio programa escribiendo un archivo de registro para cada instancia (por ejemplo: myprog.pid.log)
BitsOfNix

@LieRyan porque a menos que inicie sesión con algo como syslog, debe iniciar sesión en un archivo separado para cada proceso. Si simplemente intenta tener más de 20 procesos, escriba en el mismo archivo al mismo tiempo que lo pasará mal.
Sammitch

@Sammitch:tail -f *.log
Lie Ryan

5

Soy un usuario de KDE, con konsole 2.13.2 en KDE 4.13.3 puedes hacer esto:

  1. abrir konsole

  2. vista dividida verticalmente ingrese la descripción de la imagen aquí

  3. escribir simultáneamente en cada terminal dentro de la ventana ingrese la descripción de la imagen aquí


4

Prueba Terminator (terminal del emulador). Puede tener muchas sesiones de shell en la misma ventana y puede transmitir un comando a todas ellas.

Terminator


3

Puede utilizar una herramienta como MobaXterm y le permitirá conectarse simultáneamente y luego pegar sus comandos en todas sus ventanas.


No está relacionado con Linux, ya que mobaxterm, que es muy impresionante por lo que hace, es solo Windows y la pregunta es claramente sobre una solución de Linux.
RJ

3

Si solo desea ver la salida de la ejecución número 100 del programa:

#!/bin/bash

prog="/path/to/myprog"
args="argument1 argument2"
max=100
for i in $(seq $max); do
    if [ $i -lt $max ]; then
        exec $prog $args &> /dev/null &
    else
        exec $prog $args
    fi
done

2

Puedes controlar a konsoletravés DCOP. Un ejemplo es de aquí :

#!/bin/bash

checkfile() {
  if [ ! -f $1 ]; then
    echo "could not find $1"
    exit 99
  else
    echo "OK"
  fi
}

# Check for App1 XML
echo -n "Checking for App 1 XML... "
XMLA=/domain/DM.xml
checkfile ${DEVROOT}/${XMLA}

# Check for App2 XML
echo -n "Checking for App 2 XML... "
hostname=$(hostname)
XMLB=/domain/DM_${hostname}.xml
checkfile ${DEVROOT}/${XMLB}

# Launch Konsole
echo -n "Launching konsole... "
K=$(dcopstart konsole-script)

[ -z "${K}" ] && exit 98
# Create second tab and resize
SDA=$(dcop $k konsole currentSession)
SDB=$(dcop $k konsole newSession)
dcop $K $SDA setSize 121x25

# Let bash login, etc.
sleep 1

# Rename the tabs
dcop $K $SDA renameSession "App 1"
dcop $K $SDB renameSession "App 2"

# Start services, letting user watch
echo -n "starting app1... "
dcop $K konsole activateSession $SDA
dcop $K $SDA sendSession "echo -ne '\033]0;DEV (${hostname})\007' && clear && starter $XMLA"
sleep 2
echo -n "starting app2... "
dcop $K konsole activateSession $SDB
dcop $K $SDB sendSession "echo -ne '\033]0;DEV (${hostname})\007' && clear && starter $XMLB"
echo done.

2
sh <<-STRESS & 
$( printf 'myprog &\n%.0b' \
    `seq 1 ${MAX_CONCURRENT_PROCS}` )
STRESS
echo "$!"

Estoy de acuerdo con el comentario que hace @msw arriba. Esto le escribirá un script que se iniciará mediante un shproceso en segundo plano e imprimirá el shpid del proceso secundario para que pueda monitorearlo y sus elementos secundarios mientras funciona.


2

@ Jinpeng estaba en el camino correcto con GNU Parallel , pero no con la implementación.

Ejemplo: ejecute 10 instancias paralelas de su programa, con cada subproceso ejecutando su programa solo una vez:

parallel -j10 './myprog argument1 argument2 #' ::: {1..10}

Ejemplo: ejecute 10 subprocesos paralelos, con cada uno de esos subprocesos ejecutando su programa infinitamente:

parallel -j10 'while true ; do ./myprog argument1 argument2 ; done #' ::: {1..10}

Puede escalar esto fácilmente a los cientos de hilos reemplazando el 10en mis ejemplos.

parallel -j200     ...     ::: {1..200}

Si su programa produce mensajes estándar y desea verlos a medida que se producen (en lugar del valor predeterminado que los clasifica), la --ungroupopción de paralelo puede ser útil.

parallel --ungroup   ...

Si está ejecutando muchos subprocesos desde su estación de trabajo y no desea que las cosas no respondan, considere niceel subárbol de proceso completo en el momento del lanzamiento.

nice -n19 parallel   ...

Nota aparte, paralelo GNU normalmente no se instala de forma predeterminada, pero es por lo general en sus repositorios de paquetes normales, por lo que sólo tiene que instalar como cualquier otro paquete: dnf install parallel, apt-get install parallel, brew install parallel, etc.


1

Puede iniciar procesos en segundo plano con nohup.

Ejemplo:

nohup ./myprog -arg1 -arg2 &

Salida:

[1] 1769    
nohup: ignoring input and appending output to 'nohup.out'

Recuerde matar la tarea más tarde con lo dado PID:

kill 1769

Para poner el proceso en primer plano, debe ingresar el número de trabajo, en este caso [1]:

fg %1

1

GNU paralelo es exactamente la herramienta que está buscando. parallel -j 9 yourcommand


0

Mi pequeño molino:

#!/bin/sh

[ $# -lt 1 ] && {
        echo "Use: $0 <file>
        where file includes list of server"
        exit 9
}

cp ~/.config/terminator/config ~/.config/terminator/config.`date +%Y%m%d-%H%M`

cat ~/.config/terminator/config.`date +%Y%m%d-%H%M`|grep -v "^.plugins" >~/.config/terminator/config

inc=5
echo "  [[terms]]" >>~/.config/terminator/config
for i in `cat $1` ; do
        echo "   [[[window${inc}]]]"
        echo "       type = Window"
        echo "   [[[terminal${inc}]]]"
        echo "     profile = default"
        echo "     order = 0" 
        echo "     type = Terminal"
        echo "     parent = window${inc}"
        echo "     command = ssh $i"
        inc=$((inc+1))
done >>~/.config/terminator/config

echo "[plugins]" >>~/.config/terminator/config

Hará la configuración del terminador (términos de diseño) para muchas ventanas en un grupo.

EDITAR: al menos, el terminador puede enviar difusión a cada terminal en el mismo grupo. Esta función es conmutable, por lo que puede habilitarla para escribir 'su -' y luego deshabilitar y escribir la contraseña propia en los terminales onces y habilitarla nuevamente.


1
¿Es mejor? Disculpe mal inglés por favor :)
Marek
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.