Comment exécuter la même commande linux dans plus d'un onglet / shell simultanément?


33

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 argument2simultanément dans plus d'un 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 ultérieurement.

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


1
"Chaque fois que vous effectuez une tâche répétitive impliquant un ordinateur, automatisez-la" - moi . Je pense que vous pouvez vous rendre un mauvais service en utilisant plusieurs onglets de terminal pour les tests de charge, car vous auriez à les regarder tous, ce qui est fastidieux. Il est préférable d’avoir un programme qui génère des myproginstances enfants et agrège leur sortie pour vous.
msw

1
Le multi-threading normal ne va pas avoir un mutex entre les processus ...?
Aaron D. Marasco

@msw: Ouais, mais si je voulais voir ce que verrait l'utilisateur final quand il exécuterait la même commande depuis son terminal et quand j'aurais mis cela à l'échelle pour dire 100, que verraient-ils sur leur écran? N'est-ce pas une chose valable à déterminer?
Arpith

@ AaronD.Marasco: Je veux vérifier les mutex que j'ai installés, dans l'espace utilisateur.
Arpith

Donc, exécutez 99 instances sous un seul superviseur et exécutez une centième dans un terminal. Je vous concède que vous pourrez peut-être regarder 100 terminaux simultanément. Si c'est le cas, je suis impressionné.
msw

Réponses:


46

Comme mavillan déjà suggéré, utiliser juste terminaison . Il permet d'afficher de nombreux terminaux en mosaïque. Lorsque vous activez la fonction de diffusion, vous pouvez entrer la même commande simultanément sur chaque terminal.

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

terminatorx32


3
Zut c'est génial!
Afr

Comment puis-je facilement ouvrir 32 terminaux?
Annan

6
@Annan Terminator prend en charge les dispositions personnalisées. Consultez unix.stackexchange.com/a/168445/2594 et askubuntu.com/a/178242/18306
jlliagre le

11

tmux a cette capacité. (avec beaucoup d'autres fonctionnalités utiles dans la même veine)

Peut être fait via:

:setw synchronize-panes on

Pourriez-vous décrire brièvement comment tmux fait cela - ou coller un lien? THX!
Eli

1
: setw synchronize-panes on
Michael Martinez

9

Multixterm

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

$ multixterm

Et une fois en place, une interface graphique vous sera présentée.

                                                         ss de gui

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

   ss of xtems

diffusion sur clavier

Apparaît être uniquement disponible sur Ubuntu, ressemble à multixterm.

extrait

La diffusion au clavier a pour but d’autoriser l’envoi simultané de frappes sur plusieurs fenêtres X. 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 proposez une utilisation raisonnable de cette capacité, j'aimerais en entendre parler.

Le programme peut sélectionner les fenêtres à envoyer en faisant correspondre leurs titres (en utilisant une sous-chaîne) ou en cliquant sur eux (selon 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 en exécutant une commande unique sur plusieurs arguments (par exemple, l'exécution de 'ssh' sur plusieurs hôtes). Les gnome-terminaux sont appelés avec le profil 'keyboardcast' s'il existe (ainsi, par exemple, la taille de la police peut être plus petite).


gardiens! Note prise.
runlevel0

Il semble que la diffusion sur clavier soit interrompue, ce qui est décevant.
RJ


8

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 lors de 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 plus de travail manuel.


Pourriez-vous développer davantage sur la solution d'écran? Plus conforme à ce que je veux ...
Arpith

pourquoi ne pas simplement tail -fle fichier journal au lieu de configurer une centaine d'écrans.
Lie Ryan

@Arpith l’écran fait apparaître plusieurs terminaux dans un seul. Si vous voulez tous les voir en "temps réel", vous pouvez utiliser l'écran. Personnellement, j'irais avec les fichiers de log, vous pouvez configurer votre prog pour envoyer un message ou pour que votre propre prog écrive un fichier de log pour chaque instance (ex: myprog.pid.log)
BitsOfNix

@LieRyan parce que, sauf si vous vous connectez avec quelque chose comme Syslog, vous devez vous connecter à un fichier séparé pour chaque processus. Si vous essayez simplement de faire en sorte que plus de 20 processus écrivent dans le même fichier en même temps, vous passerez un mauvais moment.
Sammitch

@Sammitch:tail -f *.log
Lie Ryan

5

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

  1. konsole ouverte

  2. fractionner la vue verticalement entrez la description de l'image ici

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


4

Essayez Terminator (terminal émulateur). Il peut avoir plusieurs sessions de shell dans la même fenêtre et vous pouvez diffuser une commande à toutes.

Terminateur


3

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


En tant que mobaxterm, ce n’est pas lié à Linux, ce n’est que Windows et la question qui se pose est clairement une solution Linux.
RJ

3

Si vous voulez seulement voir le résultat de la 100ème exécution du 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

2

Vous pouvez contrôler à konsoletravers DCOP. Un exemple est à partir 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
sh <<-STRESS & 
$( printf 'myprog &\n%.0b' \
    `seq 1 ${MAX_CONCURRENT_PROCS}` )
STRESS
echo "$!"

Je suis d'accord avec le commentaire que @msw fait ci-dessus. Cela vous écrira un script à lancer par un shprocessus en arrière-plan et imprimera shle pid du processus enfant afin que vous puissiez le surveiller et surveiller ses enfants pendant son fonctionnement.


2

@Jinpeng était sur la bonne voie avec GNU Parallel , mais pas la mise en œuvre.

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 indéfiniment:

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 10dans mes exemples.

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

Si votre programme produit des messages stdout et que vous souhaitez les voir au fur et à mesure de leur production (plutôt que le message par défaut qui les assemble), l' --ungroupoption de mise en parallèle peut être utile.

parallel --ungroup   ...

Si vous exécutez beaucoup de threads à partir de votre poste de travail et que vous ne voulez pas que les choses ne répondent plus, prenez en compte nicel'ensemble de la sous-arborescence de processus au moment du lancement.

nice -n19 parallel   ...

Note latérale, parallèle GNU est généralement pas installé par défaut mais est habituellement dans vos prises en pension de paquet normal, donc il suffit d' installer comme tout autre paquet: dnf install parallel, apt-get install parallel, brew install parallel, etc.


1

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

Exemple:

nohup ./myprog -arg1 -arg2 &

Sortie:

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

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

kill 1769

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

fg %1

1

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


0

Mon petit moulin:

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

Confectionnera le terminateur (termes de mise en page) pour plusieurs fenêtres d'un groupe.

EDIT: au moins, le terminateur est capable d’envoyer des émissions dans chaque terminal du même groupe. Cette fonction est commutable - vous pouvez donc l'activer pour écrire 'su -' puis désactiver et écrire un mot de passe personnel pour les terminaux onces et l'activer à nouveau.


1
Est-ce mieux? Excusez-moi, anglais, s'il vous plaît :)
Marek
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.