Wie führe ich den gleichen Linux-Befehl in mehr als einer Registerkarte / Shell gleichzeitig aus?

33

Gibt es ein Tool / einen Befehl in Linux, mit dem ich einen Befehl in mehreren Registerkarten gleichzeitig ausführen kann? Ich möchte den gleichen Befehl ausführen: ./myprog argument1 argument2gleichzeitig in mehr als einer Shell, um zu überprüfen, ob die Mutexe in einem Thread-Programm einwandfrei funktionieren. Ich möchte in der Lage sein, die Anzahl der Instanzen dieses Programms zu erhöhen, um meinen Code später unter Druck zu setzen.

Ich suche so etwas wie das, was die Wand macht. Ich kann mir vorstellen, tty zu verwenden, aber das scheint nur eine Menge Schmerz zu sein, wenn ich das auf viel mehr Muscheln skalieren muss.

Arpith
quelle
1
"Jedes Mal, wenn Sie eine sich wiederholende Aufgabe ausführen, die einen Computer betrifft, automatisieren Sie diese" - ich . Ich denke, Sie können sich selbst einen schlechten Dienst leisten, indem Sie mehrere Terminal-Registerkarten für Lasttests verwenden, weil Sie sie alle ansehen müssten, was mühsam ist. Es ist besser, ein Programm zu haben, das untergeordnete myprogInstanzen erzeugt und deren Ausgabe für Sie aggregiert.
msw
1
Normales Multithreading hat keinen Mutex zwischen Prozessen ...?
Aaron D. Marasco
@msw: Ja, aber was wäre, wenn ich sehen wollte, was der Endbenutzer sehen würde, wenn er denselben Befehl von seinem Terminal aus ausführte und wenn ich diesen auf 100 skalierte, was würden sie auf ihrem Bildschirm sehen? Ist das nicht eine gültige Sache zu bestimmen?
Arpith
@ AaronD.Marasco: Ich möchte die von mir eingegebenen Mutexe im Benutzerbereich überprüfen.
Arpith
Führen Sie also 99 Instanzen unter einem Supervisor aus und führen Sie eine 100 in einem Terminal aus. Ich gebe zu, dass Sie möglicherweise 100 Terminals gleichzeitig sehen können, wenn ja, bin ich beeindruckt.
msw

Antworten:

46

Wie von mavillan bereits vorgeschlagen, verwenden Sie einfach einen Terminator . Es erlaubt, viele Terminals gekachelt darzustellen. Wenn Sie die Sendefunktion aktivieren, können Sie auf jedem Terminal denselben Befehl gleichzeitig eingeben.

Hier ist ein Beispiel mit dem Datumsbefehl, der an ein Raster von 32 Terminals gesendet wird.

terminatorx32

jlliagre
quelle
3
Verdammt, das ist großartig!
Afr
Wie kann ich problemlos 32 Terminals öffnen?
Annan
6
@Annan Terminator unterstützt benutzerdefinierte Layouts. Besuchen Sie
jlliagre
11

tmux hat diese Fähigkeit. (zusammen mit vielen anderen nützlichen Funktionen in der gleichen Richtung)

Kann erfolgen über:

:setw synchronize-panes on
Michael Martinez
quelle
könntest du bitte kurz beschreiben wie tmux das macht - oder einen link einfügen? Danke!
Eli
1
: Setw Synchronize-Scheiben auf
Michael Martinez
9

Multixterm

Ein weiteres Tool, das Sie zur Liste hinzufügen können, heißt multixterm. Es werden xtermTerminals verwendet. Sie können es folgendermaßen aufrufen:

$ multixterm

Und dann wird Ihnen eine grafische Benutzeroberfläche angezeigt.

                                                         ss von gui

Sie können dann mit dem Hochfahren von xtermFenstern beginnen, indem Sie auf die new xtermSchaltfläche klicken . Hier zum Beispiel habe ich 2 aufgerufen. Wenn Sie dann auf das primäre Fenster klicken, können Sie in beiden Fenstern gleichzeitig Befehle eingeben:

   ss von xtems

Keyboardcast

Scheint nur unter Ubuntu verfügbar zu sein, ähnelt Multixterm.

Auszug

Mit Keyboardcast können Sie Tastatureingaben an mehrere X-Fenster gleichzeitig senden. Auf diese Weise können Sie beispielsweise eine Reihe von Terminals steuern, die zu Zwecken der Massenverwaltung an unterschiedliche, aber ähnliche Hosts angeschlossen sind.

Sie können auch Nicht-Terminals auswählen. Wenn Sie eine vernünftige Verwendung für diese Fähigkeit finden, wäre ich daran interessiert, davon zu hören.

Das Programm kann Fenster zum Senden auswählen, indem sie entweder mit ihren Titeln übereinstimmen (mithilfe eines Teilstrings) oder darauf klicken (ähnlich wie bei der GIMP-Screenshot-Funktion).

Das Programm bietet auch die Möglichkeit, mehrere Instanzen von gnome-terminal zu erzeugen, die einen einzelnen Befehl mit mehreren Argumenten ausführen (zum Beispiel 'ssh' auf mehreren Hosts ausführen). Die Gnome-Terminals werden mit dem Profil 'keyboardcast' aufgerufen, wenn es existiert (so kann zum Beispiel Ihre Schriftgröße kleiner sein).

slm
quelle
Hüter! Notiz genommen.
Runlevel0
Es scheint, dass der Keyboardcast kaputt ist, was enttäuschend ist.
RJ
8

Sie können etwas tun wie:

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

Oder wenn die Ausgabe jedes Befehls während der Ausführung relevant ist, können Sie den Bildschirm einrichten.

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

Der Bildschirm erfordert mehr manuelle Arbeit.

BitsOfNix
quelle
Könnten Sie die Bildschirmlösung weiter ausbauen? Mehr im Einklang mit dem, was ich will ...
Arpith
Warum nicht einfach tail -fdie Protokolldatei anstatt hundert Bildschirme einzurichten?
Lie Ryan
@Arpith der Bildschirm erzeugt mehrere Terminals in einem. Wenn Sie alle in "Echtzeit" sehen möchten, können Sie den Bildschirm verwenden. Obwohl ich persönlich mit Logfiles arbeiten würde, können Sie Ihren Prog so einrichten, dass er eine Nachricht sendet oder dass Ihr eigener Prog für jede Instanz eine Logdatei schreibt (Beispiel: myprog.pid.log)
BitsOfNix
@LieRyan, da Sie sich für jeden Prozess in einer separaten Datei anmelden müssen, es sei denn, Sie melden sich mit so etwas wie syslog an. Wenn Sie einfach versuchen, mehr als 20 Prozesse zur gleichen Zeit in dieselbe Datei zu schreiben, werden Sie eine schlechte Zeit haben.
Sammitch
@Sammitch:tail -f *.log
Lie Ryan
5

Ich bin ein KDE-Benutzer, mit Konsole 2.13.2 unter KDE 4.13.3 können Sie dies tun:

  1. Konsole öffnen

  2. Ansicht vertikal teilen Bildbeschreibung hier eingeben

  3. Schreiben Sie gleichzeitig auf jedes Terminal im Fenster Bildbeschreibung hier eingeben

nulll
quelle
4

Versuchen Sie es mit Terminator (Emulator-Terminal). Es kann viele Shell-Sitzungen im selben Fenster geben und Sie können einen Befehl an alle senden.

Terminator

Mavillan
quelle
3

Sie könnten ein Tool wie MobaXterm verwenden, mit dem Sie gleichzeitig eine Verbindung herstellen und dann Ihre Befehle in alle Ihre Fenster einfügen können.

user46436
quelle
Nicht mit Linux verwandt, wie mobaxterm, was sehr beeindruckend ist, ist nur Windows und die Frage ist eindeutig nach einer Linux-Lösung.
RJ,
3

Wenn Sie nur die Ausgabe der 100. Programmausführung sehen möchten:

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

Sie können konsoledurch steuern DCOP. Ein Beispiel ist von hier :

#!/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.
Aaron D. Marasco
quelle
2
sh <<-STRESS & 
$( printf 'myprog &\n%.0b' \
    `seq 1 ${MAX_CONCURRENT_PROCS}` )
STRESS
echo "$!"

Ich stimme dem obigen Kommentar @msw zu. Hiermit wird ein Skript geschrieben, das von einem Hintergrundprozess gestartet wird sh, und shdie pid des untergeordneten Prozesses ausgedruckt, damit Sie ihn und seine untergeordneten Prozesse während der Ausführung überwachen können.

mikeserv
quelle
2

@ Jinpeng war mit GNU Parallel auf dem richtigen Weg , nur nicht die Implementierung.

Beispiel: Führen Sie 10 parallele Instanzen Ihres Programms aus, wobei jeder Thread Ihr Programm nur einmal ausführt:

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

Beispiel: Führen Sie 10 parallele Threads aus, wobei jeder dieser Threads Ihr Programm unendlich ausführt:

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

Sie können dies leicht auf die Hunderte von Threads skalieren, indem Sie das 10in meinen Beispielen ersetzen .

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

Wenn Ihr Programm Standardnachrichten ausgibt und Sie diese so anzeigen möchten, wie sie erstellt wurden (und nicht die Standardnachricht, in der sie sortiert werden), kann die --ungroupOption parallel nützlich sein.

parallel --ungroup   ...

Wenn Sie viele Threads von Ihrer Workstation ausführen und nicht möchten, dass die Dinge nicht mehr reagieren, sollten niceSie den gesamten Teilbaum des Prozesses zum Startzeitpunkt berücksichtigen .

nice -n19 parallel   ...

Randnotiz, GNU Parallel ist in der Regel standardmäßig nicht installiert , sondern ist in der Regel in Ihrem normalen Paket repos, so installieren Sie es wie jedes andere Paket: dnf install parallel, apt-get install parallel, brew install paralleletc.

Joshua Huber
quelle
1

Mit können Sie Prozesse im Hintergrund starten nohup.

Beispiel:

nohup ./myprog -arg1 -arg2 &

Ausgabe:

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

Denken Sie daran, die Aufgabe später mit dem folgenden Befehl abzubrechen PID:

kill 1769

Um den Prozess in den Vordergrund zu stellen, müssen Sie die Jobnummer eingeben, in diesem Fall [1]:

fg %1
TaXXoR
quelle
1

gnu parallel ist genau das Werkzeug, das Sie suchen. parallel -j 9 yourcommand

Jingpeng Wu
quelle
0

Meine kleine zu mahlen:

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

Legt die Terminatorkonfiguration (Layoutbegriffe) für viele Fenster in einer Gruppe fest.

EDIT: Zumindest kann terminator Broadcasts an jedes Terminal in derselben Gruppe senden. Diese Funktion ist umschaltbar - Sie können sie also aktivieren, indem Sie "su" schreiben. Deaktivieren und schreiben Sie dann das Passwort für einzelne Terminals und aktivieren Sie es erneut.

Marek
quelle
1
Ist es besser? Entschuldigen Sie bitte, dass ich nicht gut Englisch kann :)
Marek