Is there a way to save pid while starting a process? The script should not return to a command line, until started process finishes. And the possibility to end process by Ctrl+C should be kept.
Bash – How to start process at foreground saving it’s pid to a file
bashprocess
Related Solutions
As Stephen Kitt explains, making zsh print the PID would be rather difficult. But you can get at the information in other ways.
You can press Ctrl+Z to suspend the process, then zsh displays its PID. And if you want to kill it, try pressing Ctrl+C first, to kill it directly. If Ctrl+C fails, try Ctrl+\ for a “harder” kill (Ctrl+C sends SIGINT, which conventionally tells a program to stop its current action and hand back control to the user; Ctrl+\ sends SIGQUIT, which conventionally tells a program to crash hard). You can do this even from within Emacs: in Shell mode, press C-c C-z
to pass C-z
to the terminal, C-c C-c
to pass C-c
, C-c C-\
to pass C-\
. In Term mode, C-z
and C-\
are passed directly, but you need C-c C-c
to pass a single C-c
.
If the process changes the terminal settings or blocks the signals, a convenient way to locate it for killing is by terminal. Find out what the terminal is; you can do this with the tty
command inside the terminal. You might make this part of your prompt or part of the terminal title (I put it in the terminal title). Emacs doesn't display the terminal title, but it gives you access to the information by evaluating the following expression:
(process-tty-name (get-buffer-process (current-buffer)))
To evaluate an expression in most modes including Shell mode, type M-:
then enter the expression. In Term mode, type C-c M-x eval-expression RET
then enter the expression. If you use this often, bind the following command to a key in the relevant modes:
(defun buffer-process-tty-name ()
(interactive)
(let ((tty (process-tty-name (get-buffer-process (current-buffer)))))
(if (interactivep) (message "%s" tty))
tty))
Once you know the terminal name, you can use e.g. ps -t pts/42
or pgrep -t pts/42
to list the processes that are attached to that terminal.
I got what I needed from this answer: https://stackoverflow.com/a/41613532/1223975
..turns out using wait <pid>
will only work if that pid is a child process of the current process.
However the following will work for any process:
To wait for any process to finish
Linux:
tail --pid=$pid -f /dev/null
Darwin (requires that $pid
has open files):
lsof -p $pid +r 1 &>/dev/null
With timeout (seconds)
Linux:
timeout $timeout tail --pid=$pid -f /dev/null
Darwin (requires that $pid
has open files):
lsof -p $pid +r 1m%s -t | grep -qm1 $(date -v+${timeout}S +%s 2>/dev/null || echo INF)
Best Answer
If there's no job control, first turn on monitor mode with
More about monitor mode here: Turning off the monitor mode in Bash.