Shell: příkazy na pozadí a přepínání

šel

Shell: příkazy na pozadí a přepínání
« kdy: 24. 11. 2017, 13:02:14 »
Zdravím, zajímalo by mě, jak v shellu udělat tyto věci související s spouštěním příkazů:

1. mohu spusit nějaký příkaz na pozadí wget -o out http://neco/soubor &.   Nebo bez & na konci, s tím, poběží v popředí. Pokud zmáčknu Ctrl Z, tak se příkaz POZASTAVÍ (modelová situace: server uzavře spojení mezitím) a musím dát příkaz bg. Co když chci ten příkaz rovnou přehodit na pozadí bez přerušování (nejde mi o to, že pak mohu dát wget -C -, ale jak dostat běžící příkaz na pozadí na jeden zátah bez přerušení, což ale Ctrl Z dělá) ? Zkoušel jsem různé Zkratky Ctrl+* a nenašel odpovídající.

2. Proč příkaz (a=1;while(true); do  sleep 0.4; ((a=a+1)) ;printf "ooo %d lll\n" $a ; done ) funguje dle očekávání, že po přerušení přes  Ctrl+Z se pozastaví a lze ho obnovit, zatímco varianta bez závorek kolem celého while souvětí se po Ctrl+Z zastaví, ale po příkazu bg / fg /ručnímu zaslání signálu SIGCONT se to hned ukončí.
Vím, že () spustí nový subproces, což je vidět "i v prohlížeči úloh terminálu".  V prvním případě se zastaví celý jen podproces sleep, v druhém se zastaví podproces bash i shell.

Vrtá mi ale hlavou, proč se to neobnoví, mám 2 hypotézy (neodborně formulované:) Buď za to může příkaz sleep, který se prostě neobnoví(, což jsem ale vyloučil, když jsem si hrál s příkazem sleep 5 - při obnovení/fg/bg se obnoví čekání), takže druhá možnost je, ... nevím. Očekával jsem, že smyčka bude pokračovat... Proč?

Kód: [Vybrat]
já:~ user$ a=1;while(true); do  sleep 0.4; ((a=a+1)) ;printf "ooo %d lll\n" $a ; done
ooo 2 lll
ooo 3 lll
^Z
[1]+  Stopped                 sleep 0.4
já:~ user$ fg
sleep 0.4
já:~ user$ ----
-bash: ----: command not found
já:~ user$ (a=1;while(true); do  sleep 0.4; ((a=a+1)) ;printf "ooo %d lll\n" $a ; done )
ooo 2 lll
^Z
[1]+  Stopped                 ( a=1; while ( true ); do
    sleep 0.4; ((a=a+1)); printf "ooo %d lll\n" $a;
done )
já:~ user$ fg
( a=1; while ( true ); do
    sleep 0.4; ((a=a+1)); printf "ooo %d lll\n" $a;
done )
ooo 3 lll
ooo 4 lll
^C

3. Co dělají řídící příkazy Ctrl+ {O,M,I,U,R,J} různě umožní "psát" do výpisu, ale to je ,co pozoruji... Očko nechá běžet program, ale nevypisuje výstup.

« Poslední změna: 27. 11. 2017, 08:53:43 od Petr Krčmář »


i

Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #1 kdy: 24. 11. 2017, 13:38:32 »
Zdravím, zajímalo by mě, jak v shellu udělat tyto věci související s spouštěním příkazů ....

A opravdu to ten výstup mít musí ?

1. Můžeš zkusit screen, utilitku je obvykle třeba nainstalovat

2. Můžeš zkusit:

...$ ./delej_doblba  > vystup &
...$ tail -100 vystup
... .... ....

A mnoho dalších způsobů.
Ten první ti umožní provádět občas i nějaký vstup, ten druhý nikoliv.


šel

Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #2 kdy: 24. 11. 2017, 15:20:22 »
Ptal jsem se spíš kvůli pochopení fungování shellu a terminálu. K čemu míří dotaz , zda to opravdu musí mít výstup?
1. Mi šlo jen o to, jak provést akci "Přesunout běh  již spuštěného příkazu na pozadí, aniž by se zastavil." Důležité je již spuštěného, jinak je to jednoduché (`příkaz &`) a důležité je, aby se nepřerušil (Což v době po stisktu Ctrl+Z a `bg` je)
O screen utilitě jsem letmo slyšel, pokud vím, tak slouží na rozdělení okna terminálu a přepínání tasků. Ale připadá mi to jak kanon na vrabce.
2.  (ta odpověď je asi k něčemu jinému...)Tady se neptám na znění příkazu, ale na vysvětlení, proč  Ctrl+Z "přeruší smyčku while".

JardaP .

  • *****
  • 11 064
    • Zobrazit profil
    • E-mail
Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #3 kdy: 24. 11. 2017, 16:07:51 »
Ten prikaz se zastavi v okamziku, kdy potrebuje neco napsat, ale nema terminal, protoze jste ho hodil na pozadi. Proto dotaz na nutnost vystupu. Kdyz ten vystup presmerujete (radsi i chybovy), zastavit by se nemel.

šel

Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #4 kdy: 24. 11. 2017, 16:54:06 »
Takže to je odpověď ke dvojce ,protože např curl, i když je na pozadí, tak vypisuje progres

Upravil jsem tedy skript:
Kód: [Vybrat]
a=1;while(true);  do  sleep 0.24; ((a=a+1)) ; echo  "n: $a" >> wcr ; done a stále ale když dám ctrl+Z, tak poslední číslo, které se zapíše je to před Ctrl+Z, po fg/bg se nezapíše nic.
Teď tomu nerozumím. Hodil jsem ho napozadí a běží a chce zapisovat nebo jsem ho Zastavil (ukončil)?


JardaP .

  • *****
  • 11 064
    • Zobrazit profil
    • E-mail
Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #5 kdy: 24. 11. 2017, 18:30:30 »
Tedy bude asi problem v tom, co je pri ctrl-z povazovano za job. Podeziram, ze to bude jen prvni prikaz, tedy a=1. Takze z toho udelejte skript"
Kód: [Vybrat]
#!/bin/bash
a=1;while(true);  do  sleep 0.24; ((a=a+1)) ; echo  "n: $a" >> wcr ; done

-Zasejvujte jako test.sh, spustte bash test.sh a jinde si pustte tail -f wcr.
-Stisknete ctrl-z, vystup by se mel zastavit, job odesel na pozadi, ale stoji.
-Pustte prikaz bg, vystup by se mel zase rozbehnout.
-Jobs vypise seznam uloh.
-fg %n, kde n je cislo ulohy, ji prenese zpet do popredi.

šel

Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #6 kdy: 26. 11. 2017, 01:29:11 »
Tedy bude asi problem v tom,  Takze z toho udelejte skript"
Kód: [Vybrat]
#!/bin/bash
a=1;while(true);  do  sleep 0.24; ((a=a+1)) ; echo  "n: $a" >> wcr ; done

co je pri ctrl-z povazovano za job. Podeziram, ze to bude jen prvni prikaz, tedy a=1.
-souborová verze se chová jako ozávorkovaná verze, tedy reaguje na pauzu a obnovení
-Šlo by to nějak rozvést, ta domněnka ,proč je jen první příkaz považován za job (A zda je to pravda)?

Pak by mě ještě zajímala jedna věc: Když spustím neozávorkovanou verzi ,  dám, ctrl+z,,bg,jobs, tak příkaz jobs ještě Ukáže "zbytek" toho procesu "[1]+  Stopped "., až příkaz bg To ho nějak terminuje do stavu done.
 To be mě taky zajímalo, jestli je tu bug , nebo feature, že do ještě "pro informaci zobrazí joby, které naposled běžely". A nebo to souvisí s tím, během toho příkazu, že nějak běží-neběží podivně (protože po Stisku Ctrl-Z už nic se nedá nijak obnovit

Kód: [Vybrat]
já:~ user$ a=1;while(true); do  sleep 0.1; ((a=a+1)) ;echo $a ; done
2
3
4
^Z
[1]+  Stopped                 sleep 0.1
já:~ user$ jobs
[1]+  Stopped                 sleep 0.1
já:~ user$ jobs
[1]+  Stopped                 sleep 0.1
já:~ user$ bg
[1]+ sleep 0.1 &
[1]+  Done                    sleep 0.1
já:~ user$ jobs
já:~ user$

A ještě by mě zajímalo nová věc: Například jsem (již) spustil v shellu příkaz wget "něco.zip ;", který bude stahovat ještě půl hodiny něco. A teď jsem si rozmyslel, že chci po stažení spustit například `ffplay ~/alarm.wav`. Je nějak možné již za spuštěný příkaz "zařadit" další příkaz  ?  (Nejspíš právě s využitím jobů a jejich pojmenování %1,... . Ale pokud se to udělá jinak, tak by mě to taky zajímalo. řešení, že prostě napíšu naslepo příkaz ffplay alarm.wav <enter> nepočítám, vůbec to nevystihuje podstatu dotazu a navíc se může stát, že ten běžící program (wget v tomto případě) bude požírat vstup.

JardaP .

  • *****
  • 11 064
    • Zobrazit profil
    • E-mail
Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #7 kdy: 26. 11. 2017, 02:46:33 »
-Šlo by to nějak rozvést, ta domněnka ,proč je jen první příkaz považován za job (A zda je to pravda)?

Neslo, je to domnenka. Proste to bez zavorky nebo souboru nechrochta. Ctrl-z hodi prikaz na pozadi, nemusi to byt nutne ten prvni, muze to byt treba ten, ktery se zrovna vykonava, co ja vim? Tady by pomohlo jedine studium zdrojaku bashe.

Citace
To be mě taky zajímalo, jestli je tu bug , nebo feature, že do ještě "pro informaci zobrazí joby, které naposled běžely".

Netusim, ale zdrojak to vi. :-)

Citace
Je nějak možné již za spuštěný příkaz "zařadit" další příkaz  ?

Netusim, ale tipuji, ze byste toho chtel moc a budete si asi muset forknout bash. Autori nejspise pocitali spise s lidmi, kteri mysli pred stisknutim Enteru, nikoliv potom, anebo s lidmi, kteri si poradi jinak. Napriklad wget muzu prerusit a znovu spustit se switchem -c a vetsinou to rozdycha a ja si za nej predtim dopisu co chci. A v nejhorsim si muzete zbastlit cyklus, ktery bude hlidat ukonceni prikazu na pozadi (jmeno + PID) jednou za X vterin a az zmizi, spusti ten zbytek.

gll

Re:dotaz na shell bash (příkazy na pozadí a přepínání)
« Odpověď #8 kdy: 26. 11. 2017, 03:08:41 »
Citace
Je nějak možné již za spuštěný příkaz "zařadit" další příkaz  ?

Netusim, ale tipuji, ze byste toho chtel moc a budete si asi muset forknout bash. Autori nejspise pocitali spise s lidmi, kteri mysli pred stisknutim Enteru, nikoliv potom, anebo s lidmi, kteri si poradi jinak. Napriklad wget muzu prerusit a znovu spustit se switchem -c a vetsinou to rozdycha a ja si za nej predtim dopisu co chci. A v nejhorsim si muzete zbastlit cyklus, ktery bude hlidat ukonceni prikazu na pozadi (jmeno + PID) jednou za X vterin a az zmizi, spusti ten zbytek.

Kód: [Vybrat]
wait PID; prikaz