How can the *shell command output* buffer be kept in the background? - emacs

How can I tell emacs not to pop up the *Shell Command Output* buffer when calling a shell command like this?
(shell-command MY_COMMAND)
Currently emacs splits the current window into two, showing the (mostly irrelevant) output buffer. To me it would be completely sufficient if I could look it up later if I feel like it.

Maybe using shell-command was the root of the problem. I think I found a solution with call-process which works, although there may be a more elegant way:
(call-process-shell-command
"cat ~/.emacs.d/init.el"
nil "*Shell Command Output*" t
)

shell-command takes an optional argument OUTPUT-BUFFER where you can specify the buffer to output to. If it is t (actually not a buffer-name and not nil) it will be output in the current buffer. So we wrap this into a with-temp-buffer and will never have to bother with it:
(with-temp-buffer
(shell-command "cat ~/.emacs.d/init.el" t))

In my experience, if the shell command itself produces no output, then the emacs *Shell Command Output* buffer won't pop open.
Therefore, to avoid the output buffer, silence the output of the command.
One easy way is:
add " > /dev/null 2>&1" to the end of any shell command.
(Caveat: I'm unsure if /dev/null exists on 100% of platforms where one can run emacs, but on every Linux distro it should be fine.)
If the call to elisp function shell-command is in an elisp script, then you could change this:
(shell-command cmd)
to this:
(shell-command (concat cmd " > /dev/null 2>&1"))
If you occasionally do want to monitor the output, then you could create one wrapper function that suppresses the output via /dev/null, and one wrapper function with no suppression, and toggle between them as you wish.
The above advice was tested on: GNU Emacs 24.5.1 (x86_64-pc-linux-gnu, GTK+ Version 3.18.9) of 2017-09-20 on lcy01-07, modified by Debian

This utility function might help. It returns the actual value of the shell command
(defun shell-command-as-string (cmd)
(with-temp-buffer
(shell-command-on-region (point-min) (point-max)
cmd t)
(buffer-string)))

What's even better, is to use
(shell-command (concat cmd " 1>&2") t t)
This way, the output is saved in the error buffer, should you want to look at it. But it does not pop up automatically.

Related

How to start in the middle of command input

How can I have emacs start and be in the middle of a command input? Particularly, I want emacs to start in the middle of a command input find-file with a message in the small buffer saying:
Find file: ~/
and the cursor at the last character of it so that I can continue typing the remaining path to open the file I want.
You can execute one of the following commands on the command prompt or make a shell script containing it appropriately:
$ emacs -f find-file # if you want to start Emacs in the current direcoty
$ (cd ~; emacs -f find-file) # if you want to start Emacs in your home diretory
From the emacs(1) man page:
-f function, --funcall function
Excute the lisp function function
I have to admit that my lisp is a bit rusty, but this works for me. Drop it in your ~/.emacs file (or whatever init file you are using):
(add-hook 'emacs-startup-hook
(lambda ()
(if (= (length command-line-args) 1)
(call-interactively 'find-file))))
If you call emacs with no arguments, like this:
sawa#localhost:~$ emacs
It will invoke find-file for you. If, on the other hand, you invoke emacs with an argument, such as a filename, like this:
sawa#localhost:~$ emacs somefile.txt
It will default to just visiting somefile.txt

need help writing an emacs function

I want to write an emacs function that does the following -
1) Start a new shell named "abc".
2) Change the dir "/opt/abc"
3) In the dir run a shell command "python abc.py"
I have written the following function -
(defun abc-server ()
(interactive)
(shell-command "cd /opt/abc/")
(shell-command "python abc.py"))
The problem with the above -
1) It doesnt start a new shell
2) It doesnt change the dir.
3) When the cmd executes, it opens a browser window, which completely blocks any usage of emacs.
From shell-command's docstring (C-h f shell-command):
If COMMAND ends in ampersand, execute it asynchronously.
The output appears in the buffer `Async Shell Command'.
That buffer is in shell mode.
Also, combine it all into one command line. shell-command makes a new shell every time, so the pwd will not persist from one invocation to another.
(defun abc-server ()
(interactive)
(shell-command "cd /opt/abc/; python abc.py &"))
While #jpkotta's answer is good enough, a proper solution would use the anync primitives of Emacs. For one thing, you can only have one async shell command running at a time, whereas you can have a large number of named subprocesses.
(defun abc-server ()
(interactive)
;; Create buffer ahead of time so we can change its default directory
(save-excursion
(get-buffer-create "*abc-server*")
(cd "/opt/abc") )
(start-process "abc" "*abc-server*" "python" "abc.py") )
(I'm not altogether happy with the save-excursion hoop. I was hoping I could simply let-bind default-directory, but that didn't seem to work as I had expected. Alternatively, you could (start-process "abc" "*abc-server*" "sh" "-c" "cd /opt/abc; python abc.py").)
If you need to extend the command further, I would argue that this is a more scalable platform than the quick and dirty async shell command approach, but if this is all you are ever going to need, it doesn't matter much.

Pass text as argument to external program using emacs

Let's say I have this text in a file:
/home is where the heart is.
If for example, I select the /home text, using C-spc, is there a way of sending it to ls, so that in the end if will execute ls /home? M-| does not work.
As far as I know, there is no way to do that in Emacs directly. But everyting is possible with help of elisp:
(defun region-as-argument-to-command (cmd)
(interactive "sCommand: ")
(shell-command
(format
"%s %s"
cmd
(shell-quote-argument
(buffer-substring (region-beginning)
(region-end))))))
Try
M-| xargs ls. That is, pass "xargs ls" as the shell command on the region selected.
See xargs.
Victor's answer is a good one for the question you asked, but in your specific case you might consider using M-x ffap (find-file-at-point). This will give you a dired buffer for the /home directory.

How do I define an Emacs Lisp function to spawn a shell buffer with a particular command executed in the shell?

I am doing Rails development and find that I need to spawn a shell, rename the buffer (e.g. webrick), then kick off the command (rails s) and then do the whole thing over again if I want a rails console or rails dbconsole, rspec, spork, etc. every time I start up emacs.
I am hoping for something like this:
(defun spawn-shell ()
"Invoke shell test"
(with-temp-buffer
(shell (current-buffer))
(process-send-string nil "echo 'test1'")
(process-send-string nil "echo 'test2'")))
I don't want the shell to go away when it exits because the output in the shell buffer is important and some times I need to kill it and restart it but I don't want to lose that history.
Essentially, I want to take the manual process and make it invokable.
Any help is much appreciated
Tom
Perhaps this version of spawn-shell will do what you want:
(defun spawn-shell (name)
"Invoke shell test"
(interactive "MName of shell buffer to create: ")
(pop-to-buffer (get-buffer-create (generate-new-buffer-name name)))
(shell (current-buffer))
(process-send-string nil "echo 'test1'\n")
(process-send-string nil "echo 'test2'\n"))
It prompts for a name to use when you run it interactively (M-x spawn-shell). It creates a new buffer based on the input name using generate-new-buffer-name, and you were missing the newlines on the end of the strings you were sending to the process.
If your only problem is that the shell buffer disappears after the commands have been executed, why not use get-buffer-create instead of with-temp-buffer?

which shell-command in emacs lisp?

If I am trying to run a shell-command in an Emacs Lisp function in which I call rsync (or scp) multiple times, which shell-command variant should I use? I am currently using shell-command, which locks up Emacs until the process is done, and the output that should be visible with the --verbose to rsync is not printed; I can use shell-command with an & at the end of the command string to make it asynchronous, which does print the progress — but while it doesn't "lock up" Emacs entirely, the minibuffer repeatedly asks if I want to kill the process which is crippling in the meantime; and start-process-shell-command, which appears to halt the function only after the first file/directory is transferred; neglecting the rest when there are multiple rsync calls made through my function. None of these seem ideal, any hints?
I have had the most success using start-process myself.
(start-process "process-name"
(get-buffer-create "*rsync-buffer*")
"/path/to/rsync"
arg1
...
argn)
This will send all the output to a single buffer.
One solution might be to run the command in an actual shell buffer. Then you get to choose which one of those to run:
M-x shell
M-x eshell
M-x term
If you like that idea, you can code it up like this:
(defun my-rsync-routine ()
"run some rsync processes"
(with-temp-buffer
(shell (current-buffer))
(process-send-string nil "rsync ...")
(process-send-string nil "rsync ...")
(process-send-string nil "rsync ...")))
Read more on 'process-send-string for its usage. You might also want to have some error checking on the output from the processes.