Jak uruchomić to samo polecenie linux w więcej niż jednej karcie / powłoce jednocześnie?

33

Czy jest jakieś narzędzie / polecenie w systemie Linux, którego można użyć do uruchomienia polecenia na więcej niż jednej karcie jednocześnie? Chcę uruchomić to samo polecenie: ./myprog argument1 argument2jednocześnie w więcej niż jednej powłoce, aby sprawdzić, czy muteksy działają poprawnie w programie wątkowym. Chcę być w stanie zwiększyć liczbę wystąpień tego programu, aby później obciążać mój kod.

Szukam czegoś w rodzaju tego, co robi ściana. Mogę myśleć o użyciu tty, ale wydaje mi się, że to bardzo bolesne, jeśli muszę skalować to do wielu innych powłok.

Arpith
źródło
1
„Za każdym razem, gdy wykonujesz powtarzające się zadanie obejmujące komputer, zautomatyzuj go” - ja . Myślę, że możesz zrobić sobie krzywdę, używając wielu kart terminali do testowania obciążenia, ponieważ będziesz musiał oglądać je wszystkie, co jest uciążliwe. Lepiej mieć jeden program, który odradza myproginstancje potomne i agreguje dla nich swoje wyniki.
msw
1
Normalne wielowątkowość nie będzie mieć muteksu między procesami ...?
Aaron D. Marasco,
@ msw: Tak, ale co jeśli chciałbym zobaczyć, co zobaczyłby użytkownik końcowy, gdy uruchomił to samo polecenie z terminala i kiedy przeskalowałem to, aby powiedzieć 100, co by zobaczyli na ekranie? Czy to nie jest ważna rzecz do ustalenia?
Arpith,
@ AaronD.Marasco: Chcę sprawdzić muteksy, które wprowadziłem w przestrzeni użytkownika.
Arpith
Uruchom więc 99 instancji pod jednym przełożonym i uruchom 100. w terminalu. Przyznaję, że możesz oglądać jednocześnie 100 terminali, jeśli tak, jestem pod wrażeniem.
msw

Odpowiedzi:

46

Jak już sugerował mavillan, użyj terminatora . Umożliwia wyświetlanie wielu terminali w sposób kafelkowy. Po włączeniu funkcji rozgłaszania możesz wprowadzić to samo polecenie jednocześnie na każdym terminalu.

Oto przykład z poleceniem date wysłanym do siatki 32 terminali.

terminatorx32

jlliagre
źródło
3
Cholera, to jest niesamowite!
Afr
Jak mogę łatwo otworzyć 32 terminale?
Annan
6
@Annan Terminator obsługuje niestandardowe układy, zajrzyj na unix.stackexchange.com/a/168445/2594 i askubuntu.com/a/178242/18306
jlliagre
11

tmux ma taką możliwość. (wraz z wieloma innymi przydatnymi możliwościami w tym samym stylu)

Można to zrobić za pomocą:

:setw synchronize-panes on
Michael Martinez
źródło
czy mógłbyś krótko opisać, jak to robi tmux - lub wkleić link? dzięki!
eli
1
: setw synchronize-panes on
Michael Martinez
9

Multixterm

Kolejnym narzędziem do dodania do listy jest jedno o nazwie multixterm. Używa xtermterminali. Możesz go wywołać w następujący sposób:

$ multixterm

A kiedy się pojawi, zostanie wyświetlony interfejs GUI.

                                                         ss gui

Następnie możesz rozpocząć rozkładanie xtermokien, klikając new xtermprzycisk. Tutaj na przykład wywołałem 2. Jeśli następnie klikniesz okno główne, możesz rozpocząć wpisywanie poleceń w obu oknach jednocześnie:

   ss z xtems

cast klawiatury

Wygląda na to, że jest dostępny tylko na Ubuntu, wygląda podobnie do multixterm.

fragment

Celem emisji klawiatury jest umożliwienie wysyłania naciśnięć klawiszy do wielu okien X jednocześnie. Pozwala to na przykład kontrolować liczbę terminali podłączonych do różnych, ale podobnych hostów do celów masowej administracji.

Możesz także wybrać nieterminale. Jeśli wymyślisz rozsądne wykorzystanie tej umiejętności, chciałbym usłyszeć o tym.

Program może wybrać okna do wysłania, dopasowując ich tytuły (używając podłańcucha) lub klikając je (w metodzie podobnej do funkcji zrzutu ekranu GIMP).

Program ma również możliwość odradzania wielu instancji terminala gnome wykonującego jedną komendę na wielu argumentach (na przykład wykonując polecenie „ssh” na kilku hostach). Terminale gnome są wywoływane z profilem „keycast”, jeśli istnieje (więc na przykład rozmiar czcionki może być mniejszy).

slm
źródło
opiekunowie! Uwaga zrobiona.
runlevel0
Wygląda na to, że klawiatura jest zepsuta, co jest rozczarowujące.
RJ
8

Możesz zrobić coś takiego:

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

Lub jeśli dane wyjściowe każdego polecenia są istotne podczas wykonywania, możesz ustawić ekran.

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

Ekran wymaga więcej pracy ręcznej.

BitsOfNix
źródło
Czy możesz rozszerzyć możliwości rozwiązania ekranowego? Bardziej zgodne z tym, czego chcę ...
Arpith
dlaczego nie tylko tail -fplik dziennika zamiast setki ekranów.
Lie Ryan,
@Arpith ekran spawnuje kilka terminali w jednym. Jeśli chcesz zobaczyć je wszystkie w „czasie rzeczywistym”, możesz użyć ekranu. Chociaż osobiście wybrałbym pliki logów, możesz ustawić swój prog, aby wysyłał wiadomość lub faktycznie twój własny program napisał plik dziennika dla każdej instancji (np. Myprog.pid.log)
BitsOfNix
@LieRyan, ponieważ jeśli nie logujesz się za pomocą czegoś takiego jak syslog, musisz zalogować się do osobnego pliku dla każdego procesu. Jeśli po prostu spróbujesz mieć ponad 20 procesów zapisu do tego samego pliku w tym samym czasie, będziesz miał zły moment.
Sammitch
@Sammitch:tail -f *.log
Lie Ryan,
5

Jestem użytkownikiem KDE, z konsolą 2.13.2 w KDE 4.13.3 możesz to zrobić:

  1. otwórz konsolę

  2. podziel widok w pionie wprowadź opis zdjęcia tutaj

  3. pisz jednocześnie na każdym terminalu w oknie wprowadź opis zdjęcia tutaj

nulll
źródło
4

Wypróbuj Terminator (terminal emulatora). Może mieć wiele sesji powłoki w tym samym oknie i możesz wysłać polecenie do wszystkich z nich.

Terminator

mavillan
źródło
3

Możesz użyć narzędzia takiego jak MobaXterm, które pozwoli ci połączyć się jednocześnie, a następnie wkleić polecenia do wszystkich okien.

użytkownik46436
źródło
Nie związany z Linuksem, jak mobaxterm, który robi ogromne wrażenie pod względem tego, co robi, jest tylko Windows i pytanie wyraźnie dotyczy rozwiązania Linux.
RJ
3

Jeśli chcesz zobaczyć tylko wynik 100. wykonania programu:

#!/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.
źródło
2

Można kontrolować konsolepoprzez DCOP. Przykładem jest tutaj :

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

Zgadzam się z powyższym komentarzem @msw. Spowoduje to napisanie skryptu, który zostanie uruchomiony przez shproces działający w tle , i wydrukowanie shpid procesu potomnego , abyś mógł monitorować go i jego potomków podczas działania.

mikeserv
źródło
2

@Jinpeng był na dobrej drodze z GNU Parallel , tylko nie implementacją.

Przykład: Uruchom 10 równoległych instancji programu, z każdym wątkiem uruchamiającym program tylko raz:

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

Przykład: Uruchom 10 równoległych wątków, z których każdy z tych wątków będzie działał bez końca:

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

Możesz łatwo skalować to do setek wątków, zastępując 10w moich przykładach.

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

Jeśli twój program generuje jakieś standardowe komunikaty i chcesz je widzieć tak, jak są tworzone (zamiast domyślnego, który je zestawia), --ungroupopcja równoległa może być użyteczna.

parallel --ungroup   ...

Jeśli uruchamiasz wiele wątków ze stacji roboczej i nie chcesz, aby wszystko przestało odpowiadać, rozważ nicerozważenie poddrzewa całego procesu w czasie uruchamiania.

nice -n19 parallel   ...

Dygresja, GNU równoległy nie jest zazwyczaj instalowany domyślnie, ale zazwyczaj w normalnych repo opakowania, więc po prostu zainstalować go jak każdy inny pakiet: dnf install parallel, apt-get install parallel, brew install parallel, itd.

Joshua Huber
źródło
1

Możesz rozpocząć procesy w tle za pomocą nohup.

Przykład:

nohup ./myprog -arg1 -arg2 &

Wydajność:

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

Pamiętaj, aby zabić zadanie później za pomocą podanego PID:

kill 1769

Aby przenieść proces na pierwszy plan, musisz wprowadzić numer zadania, w tym przypadku [1]:

fg %1
TaXXoR
źródło
1

GNU równoległe jest dokładnie tym narzędziem, którego szukasz. parallel -j 9 yourcommand

Jingpeng Wu
źródło
0

Mój mały do ​​frezowania:

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

Wykona konfigurację terminatora (warunki układu) dla wielu okien w jednej grupie.

EDYCJA: Przynajmniej terminator może wysyłać rozgłoszenie do każdego terminala w tej samej grupie. Tę funkcję można przełączać - możesz więc włączyć zapisywanie su - następnie wyłącz i zapisz własne hasło na terminalach i włącz je ponownie.

Marek
źródło
1
Czy lepiej? Przepraszam źle angielski proszę :)
Marek