web-dev-qa-db-fra.com

Comment exécuter la même commande linux dans plusieurs onglets / Shell simultanément?

Existe-t-il un outil/une commande sous Linux que je peux utiliser pour exécuter une commande dans plusieurs onglets simultanément? Je veux exécuter la même commande: ./myprog argument1 argument2 simultanément dans plusieurs Shell pour vérifier si les mutex fonctionnent correctement dans un programme threadé. Je veux pouvoir augmenter le nombre d'instances de ce programme afin de mettre mon code sous tension plus tard.

Je cherche un peu ce que fait le mur. Je peux penser à utiliser des tty, mais cela me semble très pénible si je dois adapter cela à beaucoup plus de coques.

37
Arpith

Comme mavillan l'a déjà suggéré, utilisez simplement terminator . Il permet d'afficher de nombreux terminaux en mosaïque. Lorsque vous activez la fonction de diffusion en cliquant sur l'icône de la grille (en haut à gauche) et en choisissant "Tout diffuser", vous pouvez entrer la même commande simultanément sur chaque terminal.

Voici un exemple avec la commande date diffusée sur une grille de 32 terminaux.

terminatorx32

49
jlliagre

tmux a cette capacité. (ainsi que de nombreuses autres capacités utiles dans la même veine)

Peut se faire via:

:setw synchronize-panes on
11
Michael Martinez

Cela peut être réalisé en utilisant iTerm2

Référence: http://korishev.com/blog/2014/02/28/iterm2-broadcast-input/

enter image description here

10
Rajesh

Multixterm

Un autre outil à ajouter à la liste est celui appelé multixterm . Il utilise des terminaux xterm. Vous pouvez l'invoquer comme ceci:

$ multixterm

Et une fois que vous serez présenté avec une interface graphique.

ss of gui

Vous pouvez ensuite lancer la rotation des fenêtres xterm en cliquant sur new xterm bouton. Ici, par exemple, j'ai appelé 2. Si vous cliquez ensuite sur la fenêtre principale, vous pouvez commencer à taper des commandes dans les deux fenêtres simultanément:

ss of xtems

diffusion de clavier

Semble être uniquement disponible sur Ubuntu, ressemble à multixterm.

extrait

Le but de la diffusion de clavier est de vous permettre d'envoyer des séquences de touches à plusieurs fenêtres X à la fois. Cela vous permet, par exemple, de contrôler un certain nombre de terminaux connectés à des hôtes différents mais similaires à des fins d'administration de masse.

Vous pouvez également sélectionner des non-terminaux. Si vous trouvez une utilisation raisonnable de cette capacité, je serais intéressé d'en entendre parler.

Le programme peut sélectionner les fenêtres vers lesquelles envoyer en faisant correspondre leurs titres (à l'aide d'une sous-chaîne) ou en cliquant dessus (dans une méthode similaire à la fonction de capture d'écran de GIMP).

Le programme offre également la possibilité de générer plusieurs instances de gnome-terminal exécutant une seule commande sur plusieurs arguments (par exemple, exécutant 'ssh' sur plusieurs hôtes). Les terminaux gnome sont appelés avec le profil 'keyboardcast' s'il existe (ainsi, par exemple, la taille de votre police peut être plus petite).

9
slm

Vous pouvez faire quelque chose comme:

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

Ou si la sortie de chaque commande est pertinente pendant l'exécution, vous pouvez configurer l'écran.

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

L'écran nécessite un travail plus manuel.

8
BitsOfNix

Je suis un utilisateur de KDE, avec konsole 2.13.2 sur KDE 4.13.3, vous pouvez le faire:

  1. konsole ouverte

  2. vue fractionnée verticalement enter image description here

  3. écrire simultanément sur chaque terminal à l'intérieur de la fenêtre enter image description here

6
nulll

Essayez Terminator (terminal émulateur). Il peut avoir plusieurs sessions Shell dans la même fenêtre et vous pouvez diffuser une commande à chacune d'entre elles.

Terminator

4
mavillan

Si vous voulez seulement voir la sortie de l'exécution du 100e programme:

#!/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
3
John B

Vous pouvez utiliser un outil comme MobaXterm et il vous permettra de vous connecter simultanément, puis de coller vos commandes dans toutes vos fenêtres.

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

Je suis d'accord avec le commentaire de @msw ci-dessus. Cela vous écrira un script à lancer par un processus sh en arrière-plan et imprimera le pid du processus enfant sh afin que vous puissiez le surveiller ainsi que ses enfants pendant qu'il fonctionne.

2
mikeserv

@Jinpeng était sur la bonne voie avec GNU Parallel , mais pas l'implémentation.

Exemple: exécutez 10 instances parallèles de votre programme, chaque thread exécutant votre programme une seule fois:

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

Exemple: exécutez 10 threads parallèles, chacun de ces threads exécutant votre programme à l'infini:

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

Vous pouvez facilement mettre cela à l'échelle des centaines de threads en remplaçant le 10 dans mes exemples.

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

Si votre programme produit des messages stdout et que vous souhaitez les voir tels qu'ils sont produits (plutôt que la valeur par défaut qui les rassemble), le --ungroup L'option de mise en parallèle peut être utile.

parallel --ungroup   ...

Si vous exécutez un grand nombre de threads à partir de votre poste de travail et que vous ne voulez pas que les choses ne répondent plus, envisagez Niceen utilisant toute la sous-arborescence du processus au moment du lancement.

Nice -n19 parallel   ...

Note latérale, GNU Parallel n'est généralement pas installé par défaut mais se trouve généralement dans votre dépôt de package normal, alors installez-le comme n'importe quel autre package: dnf install parallel, apt-get install parallel, brew install parallel, etc.

2
Joshua Huber

Vous pouvez contrôler konsole à DCOP. Un exemple est d'ici :

#!/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
Aaron D. Marasco

gnu parallel est exactement l'outil que vous recherchez. parallel -j 9 yourcommand

1
Jingpeng Wu

Vous pouvez démarrer des processus en arrière-plan avec Nohup .

Exemple:

Nohup ./myprog -arg1 -arg2 &

Production:

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

N'oubliez pas de tuer la tâche plus tard avec le PID donné:

kill 1769

Pour mettre le processus au premier plan, vous devez entrer le numéro de travail, dans ce cas [1]:

fg %1
1
TaXXoR

Mon petit à moudre:

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

Fera la configuration de terminateur (termes de disposition) pour de nombreuses fenêtres dans un groupe.

EDIT: Au moins, le terminateur est capable d'envoyer une diffusion dans chaque terminal du même groupe. Cette fonction est commutable - vous pouvez donc l'activer en écrivant "su -", puis désactiver et écrire votre propre mot de passe sur les terminaux onces et la réactiver.

0
Marek