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.
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.
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
Cela peut être réalisé en utilisant iTerm2
Référence: http://korishev.com/blog/2014/02/28/iterm2-broadcast-input/
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.
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:
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).
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.
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.
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
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.
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.
@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 Nice
en 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.
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.
gnu parallel est exactement l'outil que vous recherchez. parallel -j 9 yourcommand
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
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.