58

Is there any tool/command in Linux that I can use to run a command in more than one tab simultaneously? I want to run the same command: ./myprog argument1 argument2 simultaneously in more than one shell to check if the mutexes are working fine in a threaded program. I want to be able to increase the number of instances of this program so as to put my code under stress later on.

I am kind of looking for something like what wall does. I can think of using tty's, but that just seems like a lot of pain if I have to scale this to many more shells.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Arpith
  • 1,091
  • 1
    "Any time you find yourself doing a repetitive task that involves a computer, automate it" — me. I think you may be doing yourself a disservice by using multiple terminal tabs for load testing because you'd have to watch them all which is tedious. Better to have one program which spawns child myprog instances and aggregates their output for you. – msw Sep 04 '13 at 01:07
  • 1
    Normal multi-threading isn't going to have a mutex between processes...? – Aaron D. Marasco Sep 04 '13 at 01:17
  • @msw: Yeah but what if I wanted to see what the end user would see when he ran the same command from his terminal and when I scaled that to say 100, what would they see on their screen? Isn't that a valid thing to determine? – Arpith Sep 04 '13 at 01:24
  • @AaronD.Marasco: I want to check the mutexes I have put in, in the user space. – Arpith Sep 04 '13 at 01:30
  • So run 99 instances under one supervisor and run a 100th in a terminal. I concede that you might be able to watch 100 terminals simultaneously, if so, I'm impressed. – msw Sep 04 '13 at 02:34
  • Possible this might be overkill for your case. But if you really want to do a high concurrency test, Tsung might be very useful for you: http://tsung.erlang-projects.org/ – replay Sep 04 '13 at 04:40
  • Go [tmux] (http://tmux.sourceforge.net/). – 41754 Sep 04 '13 at 06:24
  • @msw: We aim to impress. ;-) And my company is generous enough to provide me with as many monitors as I can stuff into my cubicle. :-p – Arpith Sep 04 '13 at 11:26
  • Arpith, are you still looking for a solution? If not, you might want to accept one of the answers provided. – jlliagre Dec 31 '14 at 09:19

15 Answers15

76

As mavillan already suggested, just use terminator. It allows to display many terminals in a tiled way. When enabling the broadcasting feature by clicking on the grid icon (top-left) and choosing "Broadcast All", you can enter the very same command simultaneously on each terminal.

Here is an example with the date command broadcasted to a grid of 32 terminals.

terminatorx32

jlliagre
  • 61,204
  • 7
    Damn this is awesome! – q9f Jul 15 '14 at 21:11
  • 1
    How can I easily open 32 terminals? – AnnanFay Sep 25 '15 at 16:38
  • 7
    @Annan Terminator supports custom layouts, have a look to http://unix.stackexchange.com/a/168445/2594 and http://askubuntu.com/a/178242/18306 – jlliagre Sep 25 '15 at 19:58
  • I ran into the problem, that my keystrokes were mutliple on some terminales when I broadcasted. The problem is discussed here https://www.claudiokuenzler.com/blog/862/terminator-terminal-inserting-each-character-twice-double-broadcast-multiple-windows. You can fix it by simply killing the ibus process with pkill ibus e.g. – Horsty Jan 09 '20 at 10:24
27

tmux has this capability. (along with many other useful capabilities in the same vein)

Can be done via:

:setw synchronize-panes on
corvec
  • 103
  • 3
Michael Martinez
  • 982
  • 7
  • 12
12

It can be achieved using iTerm2

Reference: http://korishev.com/blog/2014/02/28/iterm2-broadcast-input/

enter image description here

Rajesh
  • 101
  • 1
  • 3
  • 1
    Not Linux related, since iTerm is Mac OS only and the the question is clearly asking about a Linux solution. – R J Feb 03 '18 at 20:20
10

Multixterm

Another tool to add to the list is one called multixterm. It uses xterm terminals. You can invoke it like so:

$ multixterm

And once up you'll be presented with a GUI.

                                                         ss of gui

You can then start spinning up xterm windows by clicking the new xterm button. Here for example I've invoked 2. If you then click on the primary window, you can start typing commands in both windows simultaneously:

   ss of xtems

keyboardcast

Appears to only be available on Ubuntu, looks similar to multixterm.

excerpt

The purpose of keyboardcast is to allow you to send keystrokes to multiple X windows at once. This allows you, for example, to control a number of terminals connected to different but similar hosts for purposes of mass- administration.

You can also select non-terminals. If you come up with a reasonable use for this ability I'd be interested in hearing about it.

The program can select windows to send to either by matching their titles (using a substring) or by clicking on them (in a method similar to GIMP's screenshot feature).

The program also features the ability to spawn off multiple instances of gnome-terminal executing a single command on multiple arguments (for example executing 'ssh' on several hosts). The gnome-terminals are invoked with the profile 'keyboardcast' if it exists (so, for example, your font size can be smaller).

slm
  • 369,824
9

I'm a KDE user, with konsole 2.13.2 on KDE 4.13.3 you can do this:

  1. open konsole

  2. split view vertically enter image description here

  3. write simultaneously on each terminal inside the window enter image description here

nulll
  • 235
8

You can do something like:

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

Or if the output of each command is relevant during execution, you can setup screen.

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

The screen requires more manual work.

BitsOfNix
  • 5,117
  • Could you expand more on the screen solution? More in line with what I want... – Arpith Sep 04 '13 at 01:25
  • why not just tail -f the log file instead of setting up a hundred screens. – Lie Ryan Sep 04 '13 at 03:07
  • @Arpith the screen spawn several terminals in a single one. If you want to see all of them in "real time" then you can use screen. Although personally I would go with logfiles, you can set up your prog to send a message or actually have your own prog writing a logfile for each instance (ex: myprog.pid.log) – BitsOfNix Sep 04 '13 at 20:03
  • @LieRyan because unless you're logging with something like syslog you have to log to a separate file for each process. If you simply try to have 20+ processes write to the same file at the same time you're going to have a bad time. – Sammitch Sep 04 '13 at 23:55
  • @Sammitch: tail -f *.log – Lie Ryan Sep 05 '13 at 01:42
5

Try Terminator (emulator terminal). It can have many shell sessions in the same window and you can broadcast a command to all of them.

Terminator

mavillan
  • 3,097
3

You could use a tool like MobaXterm and it will allow you to connect simultaneously and then paste your commands into all of your windows.

  • Not Linux related, as mobaxterm, whike very impressive for what it does, is Windows only and the question is clearly about a Linux solution. – R J Feb 03 '18 at 20:26
  • @R J They could all be ssh terminals for a remote Linux host. OP asked for Linux "commands", not a Linux client. – mckenzm Aug 17 '22 at 23:14
3

If you only want to see output from the 100th program execution:

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

I agree with the comment @msw makes above. This will write you a script to be launched by a backgrounded sh process and print out the child sh process's pid so you can monitor it and its children as it works.

mikeserv
  • 58,310
2

@Jinpeng was on the right track with GNU Parallel, just not the implementation.

Example: Run 10 parallel instances of your program, with each thread running your program only once:

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

Example: Run 10 parallel threads, with each of those threads running your program infinitely:

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

You can easily scale this to the hundreds of threads by replacing the 10 in my examples.

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

If your program produces any stdout messages and you want to see them as they are produced (rather than the default which collates them), the --ungroup option to parallel may be useful.

parallel --ungroup   ...

If you are running a lot of threads from your workstation and don't want things to become unresponsive, consider niceing the whole process subtree at launch time.

nice -n19 parallel   ...

Side note, GNU Parallel is usually not installed by default but is usually in your normal package repos, so just install it like any other package: dnf install parallel, apt-get install parallel, brew install parallel, etc.

2

You can control konsole through DCOP. An example is from here:

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

gnu parallel is exactly the tool you are looking for. parallel -j 9 yourcommand

Jingpeng Wu
  • 111
  • 3
1

You can start processes in the background with nohup.

Example:

nohup ./myprog -arg1 -arg2 &

Output:

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

Remember to kill the task later with the given PID:

kill 1769

To bring the process in the foreground you must enter the jobnumber, in this case [1]:

fg %1
TaXXoR
  • 235
0

My little to mill:

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

Will make terminator config (layout terms) for many windows in one group.

EDIT: At least, terminator is able to send broadcast into every terminal in same group. This function is switchable - so you may enable it write 'su -' then disable and write owen password to onces terminals and enable it again.

Marek
  • 1