add job control
- in an interactive shell every pipeline runs in its own process group and gets the terminal while it runs in the foreground - Ctrl+Z stops the foreground job, command & starts a job in the background; finished and stopped jobs are reported before the prompt - new builtins jobs, fg, bg and wait (wait also works without job control, e.g. in scripts, where background jobs read from /dev/null) - terminal modes are saved and restored when a job stops or continues - exit and Ctrl+D warn once if there are stopped jobs - processes are waited for with wait4 (WUNTRACED) instead of exec.Cmd.Wait - pty based test for job control (Linux) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4b44cc6e72
commit
dae4087a94
6 files changed
+990
-73
No files matched your search
@@ -13,6 +13,10 @@ Built-in commands:
|
||||
set VAR=val - Set environment variable
|
||||
export VAR=val - Export environment variable
|
||||
source file - Run the commands of file in this shell (also: . file)
|
||||
jobs - List background and stopped jobs
|
||||
fg [%n] - Continue job n (default: current job) in the foreground
|
||||
bg [%n] - Continue stopped job n in the background
|
||||
wait [%n] - Wait for job n or all background jobs
|
||||
help - Show this help
|
||||
|
||||
Features:
|
||||
@@ -37,6 +41,8 @@ Features:
|
||||
a || b (b only if a failed); $? is the exit status of the last command
|
||||
- Pipes (a | b) and redirections: < file, > file, >> file, 2> file,
|
||||
2>> file, 2>&1, >&2, &> file (stdout and stderr), &>> file
|
||||
- Job control: command & runs in the background, Ctrl+Z stops the
|
||||
foreground job; jobs, fg, bg and wait manage the jobs
|
||||
- Non-interactive use: gosh -c 'command', gosh script, command | gosh;
|
||||
the exit status is the one of the last command
|
||||
- Startup files: login shells (-l or argv[0] starting with -) read
|
||||
@@ -179,7 +185,42 @@ $ grep -c error < build.log
|
||||
- Operatoren in Anführungszeichen oder mit `\` davor sind normale Zeichen: `echo "a|b" 'c>d' e\>f`.
|
||||
- Der Exit-Status einer Pipeline ist der des letzten Befehls. Beendet sich ein Befehl am Ende (z. B. `head`), bekommt der schreibende Befehl davor `SIGPIPE`, `yes | head -1` endet also sofort.
|
||||
- Die Built-ins `pwd` und `help` lassen sich umleiten und in Pipes verwenden (`help | less`). `cd`, `set`, `export`, `exit` und `quit` verändern die Shell selbst und sind in einer Pipeline nicht erlaubt.
|
||||
- Ein einzelnes `&` (Hintergrundprozesse) gibt es noch nicht, es wird als normales Zeichen übergeben.
|
||||
|
||||
### Job-Control
|
||||
|
||||
In einer interaktiven Shell läuft jede Befehlszeile (bzw. jede Pipeline) als eigener *Job* in einer eigenen Prozessgruppe:
|
||||
|
||||
```
|
||||
$ sleep 100 & # im Hintergrund starten
|
||||
[1] 12345
|
||||
$ vim notizen.txt # Ctrl+Z hält vim an
|
||||
^Z
|
||||
[2]+ Stopped vim notizen.txt
|
||||
$ jobs
|
||||
[1]- Running sleep 100 &
|
||||
[2]+ Stopped vim notizen.txt
|
||||
$ fg # vim wieder im Vordergrund
|
||||
$ bg %2 # oder: angehaltenen Job im Hintergrund weiterlaufen lassen
|
||||
```
|
||||
|
||||
| Befehl / Taste | Bedeutung |
|
||||
|----------------|---------------------------------------------------------------------------|
|
||||
| `befehl &` | startet den Befehl im Hintergrund, gosh wartet nicht auf ihn (`$?` ist 0) |
|
||||
| Ctrl+Z | hält den Vordergrund-Job an (`$?` wird 128+SIGTSTP, unter Linux 148) |
|
||||
| Ctrl+C | bricht nur den Vordergrund-Job ab, nicht die Shell |
|
||||
| `jobs` | listet laufende und angehaltene Jobs |
|
||||
| `fg [%n]` | holt Job `n` in den Vordergrund (und setzt ihn fort, falls angehalten) |
|
||||
| `bg [%n]` | setzt einen angehaltenen Job im Hintergrund fort |
|
||||
| `wait [%n]` | wartet auf Job `n` bzw. auf alle Hintergrund-Jobs |
|
||||
|
||||
- Ohne Angabe gilt der *aktuelle* Job (in `jobs` mit `+` markiert, der zuletzt angehaltene oder in den Hintergrund geschickte), `%-` ist der vorherige (`-`). `%n` und `n` meinen Job Nummer `n`.
|
||||
- Beendete Hintergrund-Jobs meldet gosh vor dem nächsten Prompt (`[1]+ Done sleep 100`, bei Fehlern `Exit N`).
|
||||
- Liest ein Hintergrund-Job vom Terminal, wird er angehalten (wie in bash), mit `fg` bekommt er die Eingabe.
|
||||
- Die Terminal-Einstellungen werden gesichert und wiederhergestellt: Nach dem Anhalten von `vim` oder `less` funktioniert der Prompt normal, nach `fg` bekommt das Programm seine Einstellungen zurück.
|
||||
- `exit` (oder Ctrl+D) mit angehaltenen Jobs warnt einmal (`there are stopped jobs`), ein zweites `exit` direkt danach beendet gosh.
|
||||
- `cd`, `set`, `export`, `exit`, `source`, `fg`, `bg` und `wait` lassen sich nicht mit `&` im Hintergrund starten.
|
||||
- In Skripten und mit `gosh -c` gibt es keine Job-Control (kein Ctrl+Z, kein `fg`/`bg`), `&` und `wait` funktionieren aber. Hintergrund-Jobs lesen dort von `/dev/null`.
|
||||
- Einen Job beenden lässt sich mit `kill` über die Prozess-ID (z. B. `kill 12345`); `kill %1` versteht gosh noch nicht.
|
||||
|
||||
### Farben
|
||||
|
||||
|
||||
Reference in new issue
Block a user