Как запустить одну и ту же команду linux в нескольких вкладках / оболочке одновременно?


33

Есть ли какой-нибудь инструмент / команда в Linux, которую я могу использовать для одновременного запуска команды на нескольких вкладках? Я хочу выполнить одну и ту же команду: ./myprog argument1 argument2одновременно в нескольких оболочках, чтобы проверить, нормально ли работают мьютексы в многопоточной программе. Я хочу иметь возможность увеличить количество экземпляров этой программы, чтобы потом подвергать свой код стрессу.

Я как бы ищу что-то вроде того, что делает стена. Я могу подумать об использовании tty, но это просто кажется большой болью, если мне нужно масштабировать это до большего количества оболочек.


1
«Каждый раз, когда вы обнаруживаете, что выполняете повторяющуюся задачу, которая включает компьютер, автоматизируйте его», - сказал я . Я думаю, что вы можете оказать себе медвежью услугу, используя несколько вкладок терминала для нагрузочного тестирования, потому что вам придется смотреть их все, что утомительно. Лучше иметь одну программу, которая порождает дочерние myprogэкземпляры и агрегирует их результаты для вас.
MSS

1
Нормальная многопоточность не будет иметь мьютекс между процессами ...?
Аарон Д. Мараско

@msw: Да, но что если бы я хотел посмотреть, что будет видеть конечный пользователь, когда он запустит ту же команду со своего терминала, и когда я измерил это до 100, что они увидят на своем экране? Разве это не действительная вещь, чтобы определить?
Арфит

@ AaronD.Marasco: Я хочу проверить мьютексы, которые я вставил, в пространстве пользователя.
Арфит

Так что запустите 99 экземпляров под одним супервизором и сотый в терминале. Я признаю, что вы могли бы смотреть 100 терминалов одновременно, если это так, я впечатлен.
четверг, 13

Ответы:


46

Как уже предлагал mavillan, просто используйте терминатор . Это позволяет отображать много терминалов мозаичным способом. При включении функции вещания вы можете вводить одну и ту же команду одновременно на каждом терминале.

Вот пример с командой date, транслируемой в сетку из 32 терминалов.

terminatorx32


3
Черт возьми, это круто!
Afr

Как я могу легко открыть 32 терминала?
Аннан

6
@Annan Terminator поддерживает пользовательские макеты, загляните на unix.stackexchange.com/a/168445/2594 и askubuntu.com/a/178242/18306
jlliagre

11

У tmux есть такая возможность. (наряду со многими другими полезными возможностями в том же духе)

Может быть сделано через:

:setw synchronize-panes on

Не могли бы вы вкратце описать, как это делает tmux, или вставить ссылку? Спасибо!
Или

1
: включил синхронизацию
Майкл Мартинес

9

Multixterm

Еще один инструмент для добавления в список называется multixterm. Он использует xtermтерминалы. Вы можете вызвать это так:

$ multixterm

И как только вы будете представлены GUI.

                                                         SS Gui

Затем вы можете начать вращать xtermокна, нажав new xtermкнопку. Вот, например, я вызвал 2. Если вы затем щелкните по главному окну, вы можете начать вводить команды в обоих окнах одновременно:

   сс xtems

keyboardcast

По-видимому, доступно только в Ubuntu, похоже на multixterm.

выдержка

Цель клавиатурной трансляции состоит в том, чтобы позволить вам отправлять нажатия клавиш в несколько окон X одновременно. Это позволяет вам, например, управлять несколькими терминалами, подключенными к разным, но похожим хостам, в целях массового администрирования.

Вы также можете выбрать нетерминалы. Если вы найдете разумное применение этой способности, мне было бы интересно услышать об этом.

Программа может выбрать окна для отправки, сопоставив их заголовки (используя подстроку) или щелкнув по ним (способом, аналогичным функции скриншота GIMP).

Программа также имеет возможность порождать несколько экземпляров gnome-терминала, выполняющих одну команду для нескольких аргументов (например, выполнение 'ssh' на нескольких хостах). Терминалы gnome вызываются с профилем клавиатурного вещания, если он существует (например, размер шрифта может быть меньше).


хранители! Примечание принято.
runlevel0

Кажется, что клавиатурная трансляция не работает, что разочаровывает.
RJ


8

Вы можете сделать что-то вроде:

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

Или, если вывод каждой команды актуален во время выполнения, вы можете настроить экран.

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

Экран требует больше ручной работы.


Не могли бы вы расширить возможности экранного решения? Больше в соответствии с тем, что я хочу ...
Arpith

почему бы не просто tail -fфайл журнала вместо настройки сотен экранов.
Ли Райан

@ За исключением экрана, появляется несколько терминалов в одном. Если вы хотите увидеть все из них в режиме реального времени, вы можете использовать экран. Хотя лично я бы пошел с лог-файлами, вы можете настроить свою прогу для отправки сообщения или на самом деле иметь собственную прогу для записи лог-файла для каждого экземпляра (например, myprog.pid.log)
BitsOfNix

@LieRyan, потому что, если вы не регистрируетесь с чем-то вроде системного журнала, вы должны войти в отдельный файл для каждого процесса. Если вы просто попытаетесь одновременно записать более 20 процессов в один и тот же файл, у вас будет плохое время.
Саммит

@Sammitch:tail -f *.log
Ложь Райан

5

Я пользователь KDE, с konsole 2.13.2 на KDE 4.13.3 вы можете сделать это:

  1. открытая консоль

  2. разделить вид по вертикали введите описание изображения здесь

  3. писать одновременно на каждом терминале внутри окна введите описание изображения здесь


4

Попробуйте Терминатор (эмулятор терминала). Он может иметь несколько сеансов оболочки в одном окне, и вы можете передать команду всем им.

терминатор


3

Вы можете использовать такой инструмент, как MobaXterm, и он позволит вам одновременно подключаться, а затем вставлять ваши команды во все ваши окна.


Не связанный с Linux, поскольку mobaxterm, который очень впечатляет своей работой, относится только к Windows, и вопрос явно в решении Linux.
RJ

3

Если вы хотите видеть только вывод из сотого выполнения программы:

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

Вы можете контролировать konsoleчерез DCOP. Пример отсюда :

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

Я согласен с комментарием, сделанным @msw выше. Это напишет вам скрипт для запуска фоновым shпроцессом и распечатает shpid дочернего процесса, чтобы вы могли следить за ним и его дочерними процессами во время его работы.


2

@Jinpeng был на правильном пути с GNU Parallel , но не с реализацией.

Пример: запустите 10 параллельных экземпляров вашей программы, причем каждый поток запускает вашу программу только один раз:

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

Пример: запустите 10 параллельных потоков, каждый из которых будет выполнять вашу программу бесконечно:

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

Вы можете легко масштабировать это до сотен потоков, заменив 10в моих примерах.

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

Если ваша программа генерирует какие-либо сообщения стандартного вывода и вы хотите видеть их в том виде, в котором они были созданы (а не по умолчанию, который их сопоставляет), --ungroupможет быть полезна опция параллельного подключения.

parallel --ungroup   ...

Если вы выполняете много потоков с вашей рабочей станции и не хотите, чтобы что-то перестало отвечать, рассмотрите niceвсе поддерево процесса во время запуска.

nice -n19 parallel   ...

Примечание стороны, GNU Parallel обычно не устанавливается по умолчанию , но, как правило , в своей обычной операции РЕПО пакета, так что просто установить его , как и любой другой пакет: dnf install parallel, apt-get install parallel, brew install parallelи т.д.


1

Вы можете запустить процессы в фоновом режиме с nohup.

Пример:

nohup ./myprog -arg1 -arg2 &

Выход:

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

Не забудьте убить задачу позже с учетом PID:

kill 1769

Чтобы вывести процесс на передний план, необходимо ввести номер задания, в этом случае [1]:

fg %1


0

Моя маленькая мельница

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

Произведет настройку терминатора (условия размещения) для многих окон в одной группе.

РЕДАКТИРОВАТЬ: по крайней мере, терминатор может отправлять трансляции в каждый терминал в той же группе. Эта функция является переключаемой, поэтому вы можете включить ее, написать «su -», затем отключить и записать пароль пользователя на терминалы onces и снова включить его.


1
Это лучше? Извините меня плохо английский, пожалуйста :)
Марек
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.