30

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.

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

15 Answers 15

44

As mavillan already suggested, just use terminator. It allows to display many terminals in a tiled way. When enabling the broadcasting feature, 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

11

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

Can be done via:

:setw synchronize-panes on
  • could you please shortly describe how tmux does that - or paste a link? thx! – eli Mar 21 '16 at 12:06
  • 1
    :setw synchronize-panes on – Michael Martinez Mar 22 '16 at 0:52
9

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).

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

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

It can be achieved using iTerm2

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

enter image description here

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

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

4

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

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 3 '18 at 20:26
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.
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
    Is it better? Excuse me unwell English please :) – Marek Nov 7 '18 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.