So, I got to separating stdout and stderr, but I get them in a wrong
order now... Here is an example Python program that I use to generate
output (store as `10.py'):
#! /usr/bin/env python
import sys
import time
for k in range (10):
sys.stdout.write ('line %d to stdout\n' % k)
sys.stderr.write ('line %d to stderr\n' % k)
time.sleep (0.2)
And the Emacs script (store as `fwd.el') to be executed as
$ emacs --batch --script fwd.el
that gives output in a wrong (compared to simply executing `./10.py'
from console, including M-x shell or M-x eshell) order:
(let ((process (make-process :name "10"
:command `(,(expand-file-name "10.py"))
:filter (lambda (_process string) (princ string))
:stderr (make-pipe-process :name "10/stderr"
:filter (lambda (_process string) (message "%s" string)))
:sentinel (lambda (&rest _ignored) (throw 'interrupted nil)))))
(while (process-live-p process)
(catch 'interrupted
(accept-process-output nil 60))))
When I run the Emacs script, I receive all stderr output line-by-line
(which is fine), but all stdout output comes in one chunk at the very
end, which is not...
I cannot really use `pty' connection type, because I want (in real
usecase, not in the script) to additionally keep stdout and stderr in
separate buffers, for possible later processing. Also, with pty I
wouldn't be able to use `message' or `princ' depending on the stream
used by the child process.
Is there any way to fix this?
Paul
Thank you, this seems to work (haven't tried separating stderr from
stdout yet). Is there a normal way to wait for asynchronous process to
terminate? Currently I have managed to make it work by throwing from
sentinel, but this feels a bit hackish, maybe there is something
better?
Currently I have something like this:
(let ((process (make-process ... :sentinel (lambda (_process
_event) (throw 'done nil)))))
(catch 'done
(while (process-live-p process)
(accept-process-output nil 60)))
...
Paul
On Sun, 6 Dec 2020 at 14:37, Zhu Zihao <all_but_last@163.com> wrote:
>
>
> IMO, in batch mode, `message` writes to stderr, `princ` writes to
> stdout. You can install a filter for childprocess, and run functions I
> mentioned above to forward these outputs.
>
>
> Paul Pogonyshev writes:
>
> > Hi,
> >
> > I'm using Emacs in batch mode. I need to invoke a child process that
> > is a longish operation (a few minutes). During this time, it writes to
> > its stdout, so user will see that it is working and what exactly is
> > being done. However, if I invoke it from Emacs (e.g. using
> > `call-process') I see no way of forwarding this output to the "real"
> > stdout. So, for a user this looks like the process (or batch Emacs on
> > top of it) is hung.
> >
> > Am I missing a way to forward output?
> >
> > Paul
>
>
> --
> Retrieve my PGP public key: https://meta.sr.ht/~citreu.pgp
>
> Zihao