Basically,
(uiop:run-program "echo hello" :output *standard-output*)
outputs hello, while none of
(uiop:launch-program "echo hello" :output *standard-output*)
(uiop:launch-program "echo hello" :output #.*standard-output*)
(uiop:launch-program "echo hello" :output :interactive)
output anything; however, if I do run
(uiop:run-program "echo hello" :output *standard-output*)
after them, I do get hello 4 times indicating echo hello did run. Why is this the case? ((force-output) doesn't change anything either.)
Edit: I am using SBCL with SLIME. And as suggested in the comments, this works as-expected (I get the output) on running it from the terminal.
When you look at the implementations of run-program and launch-program, you see that the former (in this case…) does a wait-process.
If you issue a uiop:wait-process on the process-info returned by launch-program, your output appears.
I guess that it is a kind of race condition where swank or slime doesn't get to pick up the output before it does something else. I think that this is inherent in the asynchronous behaviour of launch-program.
I think that the clearest way to get the output is to specify :output :stream and then use the stream available from calling process-info-output on the return value of launch-program.
Related
I want to have the ability to execute statements on R's REPL with the option to pipe it to a buffer so I can quickly refer back to it later.
To run a shell command and output to *shell command buffer* I can use M-! as per this question. What would the equivalent be for R's REPL without resorting to write.csv()?
You can use ess-command from ess-inf to redirect the output to another buffer. An example could look like the following,
(defun redirect-ess-output (command &optional buffer process)
(interactive (list (read-from-minibuffer "Command: ")))
(let ((buff (get-buffer-create (or buffer "*r-output*")))
;; 'ess-get-process' defaults to process local to current
;; buffer, so to call from anywhere default to "R"
(proc (ess-get-process (or process "R"))))
;; send a trailing newline to process
(unless (string-match-p "\n$" command)
(setq command (concat command "\n")))
(ess-command command buff 'sleep nil nil proc)
(with-current-buffer buff
;; process stuff
(pop-to-buffer buff))))
Recently I find a run-program hang issue of sbcl 1.2.7 (32bits, linux). The code as following
(progn
(with-open-file (s "test.out" :direction :output :if-exists :supersede)
(loop repeat 900 do (write-line (make-string 76 :initial-element #\x) s)))
(run-program "/bin/bash" (list "-c" "cat test.out") :output :stream))
That is when the "cat test.out" produce many lines of output to the process-output stream of process object, the `run-program' call hang forever. On my test machine, when the number of lines larger than 900, this issue happens. Otherwise just fine. I doubt this issue caused by some kind of block (maybe buffer is full?) when the output data written to the process-output stream. If we change the code as following (avoid data written to the process-output stream), the run-program call returns immediately:
(length
(with-output-to-string (s)
(run-program "/bin/bash" (list "-c" "cat test.out")
:output s)))
;;=> 69300
I don't know whether that's a bug. Is there method by which we can make the call just return when the hang issue happens?
There is also a similar question: how-to-read-from-large-process-output-correctly , but I don't get the answer why the run-program call hang there.
I also think that could be some buffer problem. However, if you read from :stream line by line, that works fine:
(let ((process
(run-program "/bin/bash" (list "-c" "cat test.out") :output :stream :wait nil)))
(loop for line = (read-line (process-output process) nil :eof)
until (eq line :eof)
do (print line)))
I am writing some code in Emacs Lisp where I want to start a subprocess using start-process or a similar function. However, when the parent emacs process exits, I don't want the subprocess to exit. However, it seems that exiting the parent emacs process always kills all the subprocesses as well. The following code snippet demonstrates this:
(require 'async)
(async-sandbox
(lambda ()
(require 'package)
(package-initialize)
(require 'async)
(shell-command "{ echo -n 'SPAWNING: '; date; } > ~/temp/ASYNC_LOG")
(start-process-shell-command "subproc" nil
"{ echo -n 'STARTED: '; date; } >> ~/temp/ASYNC_LOG;
sleep 5;
{ echo -n 'FINISHED: '; date; } >> ~/temp/ASYNC_LOG;")
(shell-command "{ echo -n 'SPAWNED: '; date; } >> ~/temp/ASYNC_LOG")
(shell-command "sleep 2")
(shell-command "{ echo -n 'FINISHED WAITING: '; date; } >> ~/temp/ASYNC_LOG")
))
This code spawns one emacs process synchronously (async-sandbox (lambda () ...) so that we can quit that process to trigger the problem. That process then spawns a subprocess asynchronously (start-process-shell-command ...). The parent process sleeps for 2 seconds, while the subprocess sleeps for 5, so the parent process will exit first. When I run this code, I never see the "FINISHED" line in the log file, indicating that the subprocess is killed after 2 seconds. If I change the parent to wait for 7 seconds, then I see the FINISHED line in the output.
So is there any similar way to start a subprocess so that it won't be killed when its parent exits?
Here's how I start stuff from dired:
(require 'dired-aux)
(setq dired-guess-shell-alist-user
'(("\\.pdf\\'" "evince")
("\\.eps\\'" "evince")
("\\.jpe?g\\'" "eog")
("\\.png\\'" "eog")
("\\.gif\\'" "eog")
("\\.tex\\'" "pdflatex" "latex")
("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\)\\'" "vlc")))
(defvar dired-filelist-cmd
'(("vlc" "-L")))
(defun dired-start-process (cmd &optional file-list)
(interactive
(let ((files (dired-get-marked-files t current-prefix-arg)))
(list
(dired-read-shell-command "& on %s: " current-prefix-arg files)
files)))
(apply
#'start-process
(list cmd nil shell-file-name shell-command-switch
(format "nohup 1>/dev/null 2>/dev/null %s \"%s\""
(if (> (length file-list) 1)
(format "%s %s"
cmd
(cadr (assoc cmd dired-filelist-cmd)))
cmd)
(mapconcat #'expand-file-name file-list "\" \"")))))
What Emacs does upon termination is to send a signal to its spawned processes (I assume they are those present in process-list). This behavior is hardcoded in Emacs C code (you could try to hack process-list removing the process you want to outlive Emacs, but I am not sure about the side effects of that; possibly they will be ugly)
You can find out what signal Emacs sends easily (just write a signal handler for one of your processes). I would guess it is SIGHUP, so the processes know that connection to the user (Emacs) has been lost.
What you can do is to make your process to handle SIGHUP in such a way it does not die, by adding a handler for that signal for instance. If you have zero control over that process code, you may wrap it with a "nohup" (this is what #abo-abo is basically doing; see abo-abo other answer for implementation details)
Try using call-process-shell-command with the destination argument set to 0.
From the documentation of call-process:
The argument destination says where to put the process output. Here are the possibilities:
…
0
Discard the output, and return nil immediately without waiting for the subprocess to finish.
In this case, the process is not truly synchronous, since it can run in parallel with Emacs; but you can think of it as synchronous in that Emacs is essentially finished with the subprocess as soon as this function returns.
MS-DOS doesn’t support asynchronous subprocesses, so this option doesn’t work there.
(From an answer by dalanicolai on https://emacs.stackexchange.com/questions/22363/possible-to-detach-a-child-process/65040#65040)
Common Lisp's multiline comments make it easier to include multiline shebangs:
#!/bin/bash
#|
exec clisp -q -q $0 $0 ${1+"$#"}
exit
|#
;;; Usage: ./scriptname.lisp
(defun main (args)
(let ((program (car args)))
(format t "Program: ~a~%" program)
(quit)))
Without this syntax, only very simple shebangs can be used. Is there a pound-based multiline comment for Smalltalk that would facilitate multiline shebangs?
It doesn't NEED to be multi-line; as long as bash can see "into" the Smalltalk comment, you should be okay. I'd be more worried about Smalltalk seeing past the #!
How about something based on:
"exec" "/usr/bin/gst" "--foo" "$0" "--bar" "$#"
There's no need for exit unless you expect the exec ever to fail. Make sure your Smalltalk is where you expect it to be! If you do want the safety valve:
"exec" ...
"exit"
Having to double-quote arguments can get in the way, of course. Double-quoting shell operators breaks their specialness, for example.
"echo" "hello" ">" "/dev/null"
just prints "hello > /dev/null"
Right now, I have F5 set to start gdb in emacs for me:
(global-set-key [f5] 'gdb)
This switches to the mini-buffer, which I then type a path to an executable... I'd like to find a way to bypass this path typing...
I wrote an executable that looks at the Makefile, parses it and figures out the full path of the executable and prints it to standard out... Is it possible to call this from my .emacs... And then somehow pass the output to the gdb command?
(defun gdb-getpath ()
"Figures out the path to executable and launches gdb."
(interactive)
(let ((path (shell-command-to-string "/path/to/your/executable")))
(gdb (concat "gdb " path))
))
(global-set-key [f5] 'gdb-getpath)