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.

9
  • 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 4, 2013 at 1:07
  • 1
    Normal multi-threading isn't going to have a mutex between processes...? Sep 4, 2013 at 1: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 4, 2013 at 1:24
  • @AaronD.Marasco: I want to check the mutexes I have put in, in the user space.
    – Arpith
    Sep 4, 2013 at 1: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 4, 2013 at 2:34

15 Answers 15

75

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

4
27

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

Can be done via:

:setw synchronize-panes on
2
  • 1
    could you please shortly describe how tmux does that - or paste a link? thx!
    – MacMartin
    Mar 21, 2016 at 12:06
  • 2
    :setw synchronize-panes on Mar 22, 2016 at 0:52
12

It can be achieved using iTerm2

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

enter image description here

1
  • 1
    Not Linux related, since iTerm is Mac OS only and the the question is clearly asking about a Linux solution.
    – R J
    Feb 3, 2018 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).

2
  • keepers! Note taken.
    – runlevel0
    Sep 13, 2016 at 9:27
  • It seems that keyboardcast is broken, which is disappointing.
    – R J
    Feb 3, 2018 at 20:15
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

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.

5
  • Could you expand more on the screen solution? More in line with what I want...
    – Arpith
    Sep 4, 2013 at 1:25
  • why not just tail -f the log file instead of setting up a hundred screens.
    – Lie Ryan
    Sep 4, 2013 at 3: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 4, 2013 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 4, 2013 at 23:55
  • @Sammitch: tail -f *.log
    – Lie Ryan
    Sep 5, 2013 at 1: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

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.

2
  • 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 3, 2018 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, 2022 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
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.
0
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.

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.

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
1

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

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.

1
  • 1
    Is it better? Excuse me unwell English please :)
    – Marek
    Nov 7, 2018 at 17:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .