Emacs and Long Shell Commands - shell

Is there a way to run a shell command, have the output show up in a new buffer and have that output show up incrementally? Eshell and other emacs terminal emulators do a find job of this but I see no way to script them.
What I'd like to do is write little elisp functions to do stuff like run unit tests, etc. and watch the output trickle into a buffer.
The elisp function shell-command is close to what I want but it shows all the output at once when the process finishes.

As doublep mentioned, there is M-x compile, and there's also just the simple M-x shell and in that shell you run whatever you want.

You can also use comint-run to execute a command without needing to start a sub-shell first. I believe M-x shell uses comint mode with some modifications, so this won't be a whole lot different from that. But if you want to call a program directly and have its input and output be tied to a buffer, comint-run is the function to call. It is a little tricky to use, so read the documentation: C-h f comint-run.

Related

emacs elisp switch to buffer and follow

I am trying to write a command that will cause Emacs to switch to a new buffer and do something (in this case, execute a shell command) that writes output to the buffer.
(defun test-func ()
(interactive)
(let ((bname "*temp*")
(default-directory "/home/me"))
(with-output-to-temp-buffer bname
(switch-to-buffer bname)
(shell-command "ls -l" bname))))
In this case, it "works" except that it doesn't switch the buffer until after the command is done executing. I wanted to switch immediately and then follow the output as it's running. Is there a way to do that?
You need to call redisplay explicitly after switch-to-buffer to make it visible.
Note that ls is a fairly "fast" command, and it is unlikely to show piecemeal. You might want to try a shell script like
while true; do
date
sleep 10
done
and run is asynchronously (either use async-shell-command or add & to the end of the command line).
Note also that the help for shell-command says:
In Elisp, you will often be better served by calling call-process or
start-process directly, since it offers more control and does not impose the use of a shell (with its need to quote arguments).

Emacs `shell` and `eshell` on Windows

I have some of the console commands I would like to use from Emacs, namely ag. It works great in CMD or Far Manager. However when I use it from Emacs shell or eshell I run into a problem which may be (slight chance, though) ag-specific.
When I run shell and then run ag it returns result (help screen) immediately. If I run it searching for a line in files inside directory as ag needle, it hangs and doesn't return anything.
If I run it as ag needle . it returns result immediately, however missing file names and lines numbers, --color and -nogroup options do not affect the printed result in this case.
When I run it via shell-command it returns the correct result (with file names and line numbers). eshell has the same problem.
What do I need to do to make these commands work in shell and/or eshell ?
It's been noted in the answers to this question that Win32 has issues with subprocess buffering. Is there a way to fix it?

How to read from terminal in lazarus on ubuntu

Lazarus can run bash scripts and commands. How to get the output of an executed command as string and later use it, for example print it with ShowMessage? Thanks!
Summary:
use the tprocess class from unit process, that allows to trap console output using pipes.
for straightforward cases use the Runcommand helper functions (also in process, wrap tprocess for simple cases)
Be aware that while you see console output as one stream, in fact there might be two (stdout and stderr)

Run emacs lisp command from inferior shell

How do I call an emacs lisp function programmatically from an inferior shell?
For instance, I'm in a shell that uses some characters that emacs recognizes and attempts to autoexpand, so I want to run this command (setq comint-input-autoexpand nil) to apply it to the shell I'm in.
I can do this now by entering the text of the command in the shell and running something like eval-region on it but I want my shell to be able to invoke this command itself.
Thanks to the people who responded but it seems my question is unclear. I can accomplish what I want by entering an elisp expression, selecting it, and calling 'eval-region' on it but this requires manual input. What I want is a way to automate this so my shell can send emacs a command to change its own settings.
The "emacsclient" suggestion seems like it's in the right direction but I'm afraid that Windows does not fully support its options and it's unclear that such a command would affect the buffer from which I invoke it since I would do so via an external "shell" command.
What I want is some sort of escape sequence that signals emacs "This elisp expression is for you". I'm guessing there might be a way to open a socket to emacs and send it commands this way but I still have the problem of selecting the buffer to which to apply the command. Again, this is probably more difficult/impossible in Windows, so I will rely on my command bound to a key sequence for now.
It sounds like you are looking for M-x eval-expression, bound by default to M-: (Alt+Colon, i.e. Alt+Shift+semicolon). The expression is evaluated in whatever context you were in when eval-expression was invoked, so if the expression sets a buffer-local variable, it will be set for your current buffer.
You can use emacsclient to do it. You'll need to have started emacs as a server, either with (server-start) in your .emacs or by starting emacs as a background process with --daemon.
You can evaluate elisp code in your shell like this:
emacsclient --eval '(setq comint-input-autoexpand nil)'

How to call bash commands from tcl script?

Bash commands are available from an interactive tclsh session. E.g. in a tclsh session you can have
% ls
instead of
$ exec ls
However, you cant have a tcl script which calls bash commands directly (i.e. without exec).
How can I make tclsh to recognize bash commands while interpreting tcl script files, just like it does in an interactive session?
I guess there is some tcl package (or something like that), which is being loaded automatically while launching an interactive session to support direct calls of bash commans. How can I load it manually in tcl script files?
If you want to have specific utilities available in your scripts, write bridging procedures:
proc ls args {
exec {*}[auto_execok ls] {*}$args
}
That will even work (with obvious adaptation) for most shell builtins or on Windows. (To be fair, you usually don't want to use an external ls; the internal glob command usually suffices, sometimes with extra help from some file subcommands.) Some commands need a little more work (e.g., redirecting input so it comes from the terminal, with an extra <#stdin or </dev/tty; that's needed for stty on some platforms) but that works reasonably well.
However, if what you're asking for is to have arbitrary execution of external programs without any extra code to mark that they are external, that's considered to be against the ethos of Tcl. The issue is that it makes the code quite a lot harder to maintain; it's not obvious that you're doing an expensive call-out instead of using something (relatively) cheap that's internal. Putting in the exec in that case isn't that onerous…
What's going on here is that the unknown proc is getting invoked when you type a command like ls, because that's not an existing tcl command, and by default, that command will check that if the command was invoked from an interactive session and from the top-level (not indirectly in a proc body) and it's checking to see if the proc name exists somewhere on the path. You can get something like this by writing your own proc unknown.
For a good start on this, examine the output of
info body unknown
One thing you should know is that ls is not a Bash command. It's a standalone utility. The clue for how tclsh runs such utilities is right there in its name - sh means "shell". So it's the rough equivalent to Bash in that Bash is also a shell. Tcl != tclsh so you have to use exec.

Resources