Running Windows batch files from Emacs - windows

I'm somewhat new to gnu emacs, and so perhaps this is a noob question, but I have a few batch files I use a lot when coding in emacs to compile/build/execute/debug/etc. I am wondering how I could A) run these batch files from emacs without having to keep opening a cmd prompt window or going to windows explorer and B) bind this to a key shortcut (perhaps I could specify the file?) I have seen several things online about running emacs in batch-mode, but I don't believe this is what I'm looking for. And I know it is possible because I have seen others run batch from emacs (output and everything would appear in a new buffer adjacent to the current as if you did C-x 3)
Thanks in advance!

To run an arbitrary shell command in Emacs, you call shell-command which is bound to M-!
See C-hf shell-command (or C-hkM-!) for details.
I believe in the Windows-native Emacs, the default shell is cmd (or some alias thereof), so I'm reasonably confident that this is what you're thinking of.
I'm not sure whether all of the following work in Windows, but related commands are:
M-& - async-shell-command
M-| - shell-command-on-region
And with a prefix argument (e.g. C-uM-!) any of those commands will insert the shell command's output into the current buffer. (In the case of shell-command-on-region, that replaces the region.)

Related

How to prevent Emacs from duplicating shell commands?

I always use Emacs's shell. I create 2 buffers (C-x 2) and use one of them as a terminal (M-x shell).
Sometimes I use a command a lot of times (e. g. python3 test.py). I use shortcut <C-up> to repeat the last command. And it's very inconvenient that Emacs saves duplicates of commands. I have to press <C-up> many times so that I can run any other command.
The problems is only in Emacs's shell. I have setting HISTCONTROL=ignoreboth in .bashrc and in usual terminal it works very well.
Is it possible to configure Emacs so that it ignores duplicates?
It's customizable
(setq comint-input-ignoredups t)
Setting 'comint-input-ignoredups' as suggested by Jürgen Hötzel will of course solve the immediate, but here are some alternatives.
You could choose to use the command 'ansi-term' instead of 'shell', this will run a bash (or whatever you choose) so you get the same control as in (say) an xterm. As an added bonus, you also get a rather capable terminal so applications that depend on this will work.
Another possibility, if you have something you want to repeatedly run, is to use the 'compile' command. This can run any shell command, it does not have to be a compiler. The advantage here is that you keep the running of the test out of your shell command history (no matter how you run your shell) and you get the output in a separate buffer. If the output is suitably organised and/or the compilation buffer is suitably configured, you could also use the 'next-error' command to jump back to the appropriate part of the source.
Finally, I would like to mention that the 'shell' command supports searching the command history. It is by default bound to M-r (comint-history-isearch-backward-regexp).

Emacs custom shell commands

Is there a possability in Emacs to run custom commands or a set of commands (eg. shell) with a user defined emacs shortcut/hook?
To make this clearer. I am working with an embedded system (target), but developing on the host. After writing and compiling code (eg using emacs compile command), I would like to copy (eg. scp) the binary to the system right away.
Furthermore it would be good if the custom shorcut/hook would be easy to adjust (eg. ip address of the target).
Btw: I am aware of the "shell-command" in emacs, but that is not quite what I am looking for.
Would appreciate any advice. Thanks!
I ended up using C-x C-f /root#my-target-ip:/tmp/myfile to edit the file directly on the target. Then you can run it with shell-command ./myfile from within emacs.

What is the Bash file extension?

I have written a bash script in a text editor, what extension do I save my script as so it can run as a bash script? I've created a script that should in theory start an ssh server. I am wondering how to make the script execute once I click on it. I am running OS X 10.9.5.
Disagreeing with the other answers, there's a common convention to use a .sh extension for shell scripts -- but it's not a useful convention. It's better not to use an extension at all. The advantage of being able tell that foo.sh is a shell script because of its name is minimal, and you pay for it with a loss of flexibility.
To make a bash script executable, it needs to have a shebang line at the top:
#!/bin/bash
and use the chmod +x command so that the system recognizes it as an executable file. It then needs to be installed in one of the directories listed in your $PATH. If the script is called foo, you can then execute it from a shell prompt by typing foo. Or if it's in the current directory (common for temporary scripts), you can type ./foo.
Neither the shell nor the operating system pays any attention to the extension part of the file name. It's just part of the name. And by not giving it a special extension, you ensure that anyone (either a user or another script) that uses it doesn't have to care how it was implemented, whether it's a shell script (sh, bash, csh, or whatever), a Perl, Python, or Awk script, or a binary executable. The system is specifically designed so that either an interpreted script or a binary executable can be invoked without knowing or caring how it's implemented.
UNIX-like systems started out with a purely textual command-line interface. GUIs like KDE and Gnome were added later. In a GUI desktop system, you can typically run a program (again, whether it's a script or a binary executable) by, for example, double-clicking on an icon that refers to it. Typically this discards any output the program might print and doesn't let you pass command-line arguments; it's much less flexible than running it from a shell prompt. But for some programs (mostly GUI clients) it can be more convenient.
Shell scripting is best learned from the command line, not from a GUI.
(Some tools do pay attention to file extensions. For example, compilers typically use the extension to determine the language the code is written in: .c for C, .cpp for c++, etc. This convention doesn't apply to executable files.)
Keep in mind that UNIX (and UNIX-like systems) are not Windows. MS Windows generally uses a file's extension to determine how to open/execute it. Binary executables need to have a .exe extension. If you have a UNIX-like shell installed under Windows, you can configure Windows to recognize a .sh extension as a shell script, and use the shell to open it; Windows doesn't have the #! convention.
You don't need any extension (or you could choose an arbitrary one, but .sh is a useful convention).
You should start your script with #!/bin/bash (that first line is understood by execve(2) syscall), and you should make your file executable by chmod u+x. so if your script is in some file $HOME/somedir/somescriptname.sh you need to type once
chmod u+x $HOME/somedir/somescriptname.sh
in a terminal. See chmod(1) for the command and chmod(2) for the syscall.
Unless you are typing the whole file path, you should put that file in some directory mentioned in your PATH (see environ(7) & execvp(3)), which you might set permanently in your ~/.bashrc if your login shell is bash)
BTW, you could write your script in some other language, e.g. in Python by starting it with #!/usr/bin/python, or in Ocaml by starting it with #!/usr/bin/ocaml...
Executing your script by double-clicking (on what? you did not say!) is a desktop environment issue and could be desktop specific (might be different with
Kde, Mate, Gnome, .... or IceWM or RatPoison). Perhaps reading EWMH spec might help you getting a better picture.
Perhaps making your script executable with chmod might make it clickable on your desktop (apparently, Quartz on MacOSX). But then you probably should make it give some visual feedback.
And several computers don't have any desktop, including your own when you access it remotely with ssh.
I don't believe it is a good idea to run your shell script by clicking. You probably want to be able to give arguments to your shell script (and how would you do that by clicking?), and you should care about its output. If you are able to write a shell script, you are able to use an interactive shell in a terminal. That it the best and most natural way to use a script. Good interactive shells (e.g. zsh or fish or perhaps a recent bash) have delicious and configurable autocompletion facilities and you won't have to type a lot (learn to use the tab key of your keyboard). Also, scripts and programs are often parts of composite commands (pipelines, etc...).
PS. I'm using Unix since 1986, and Linux since 1993. I never started my own programs or scripts by clicking. Why should I?
just .sh.
Run the script like this:
./script.sh
EDIT: Like anubhava said, the extension doesn't really matter. But for organisational reasons, it is still recommended to use extensions.
I know this is quite old now but I feel like this adds to what the question was asking for.
If your on a mac and you want to be able to run a script by double clicking it you need to use the .command extension. Also same as before make file executable with chmod -x.
As was noted before, this isn't really that useful tbh.
TL;DR -- If the user (not necessarily the developer) of the script is using a GUI interface, it depends on what file browser they are using. MacOS's Finder will require the .sh extension in order to execute the script. Gnome Nautilus, however, recognizes properly shebanged scripts with or without the .sh extension.
I know it's already been said multiple times the reasons for and against using an extension on bash scripts, but not as much why or why not to use extensions, but I have what I consider to be a good rule of thumb.
If you're the type who hops in and out of bash and using the terminal in general or are developing a tool for someone else who does not use the terminal, put a .sh extension on your bash scripts. That way, users of that script have the option of double-clicking on that file in a GUI file browser to run the script.
If you're the type who primarily does all or most of your work in the terminal, don't bother putting any extension on your bash scripts. They would serve no purpose in the terminal, assuming that you've already set up your ~/.bashrc file to visually differentiate scripts from directories.
Edit:
In the Gnome Nautilus file browser with 4 test files (each with permissions given for the file to be executed) with stupidly simple bash command to open a terminal window (gnome-terminal):
A file with NO extension with #!/bin/bash on the first line.
It worked by double-clicking on the file.
A file with a .sh extension with #!/bin/bash on the first line.
It worked by double-clicking on the file.
A file with NO extension with NO #!/bin/bash on the first line.
It worked by double-clicking on the file...technically, but the GUI gave no indication that it was a shell script. It said it was just a plain text file.
A file with a .sh extension with NO #!/bin/bash on the first line.
It worked by double-clicking on the file.
However, as Keith Thompson, in the comments of this answer, wisely pointed out, relying on the using the .sh extension instead of the bash shebang on the first line of the file (#!/bin/bash) it could cause problems.
Another however, I recall when I was previously using MacOS, that even properly shebanged (is that a word?) bash scripts without a .sh extension could not be run from the GUI on MacOS. I would love for someone to correct me on that in the comments though. If this is true, it would prove that there is a least one file browser out there where the .sh extension matters.

Emacs shell: command history lost after restart

A very useful time-saver for working with shell is that you can search for command history using Ctrl - r. Emacs has the same functionality in its shell mode: C-S-r. However, the shell's history is cleared every time emacs is restarted. Any idea how to persist the history?
In general the answer would be:
M-x customize-group RET savehist RET
Enable savehist-mode and configure the variables you wish to persist between sessions.
However in this case I think you'll find that it's your shell which is tracking its command history; not Emacs.
e.g. for bash, commands are stored in $HISTFILE (by default ~/.bash_history), but depending on your settings, the history from one shell may be clobbered by another shell, depending on which one exits last. For bash, read the HISTORY section of its man page.
Edit: For comint-mode and derivatives (including shell-mode) the searchable history is read in via comint-read-input-ring, which uses comint-input-ring-file-name which you can set in a mode hook. However I would suggest that you actually set your HISTFILE environment variable to ~/.zsh_history because shell-mode automatically defers to that.
It seems a little odd to me that zsh doesn't already do this, mind (assuming you're starting Emacs from a zsh shell?). If you use some kind of GUI launcher, OTOH, the environment Emacs starts in may not be what you want? I couldn't say for sure.
Failing that, the documentation suggests that this ought to work:
(add-hook 'shell-mode-hook 'my-shell-mode-hook)
(defun my-shell-mode-hook ()
(setq comint-input-ring-file-name "~/.zsh_history")
(comint-read-input-ring t))
(but using HISTFILE would be better).
n.b. I'm using Emacs 24.3 and the keybindings are different to those you have described (M-r to search the history in shell-mode; C-S-r is unbound for me), so YMMV. I always run my shells inside ansi-term, so I couldn't tell you whether this functionality has changed recently.

bash script on cygwin - seems to get stuck between consecutive commands.

I am using a bash script to run a number of application (some repeatedly) on a Windows machine through cygwin. The script contains commands to launch those applications, line by line. Most of these applications run for many minutes and many times I have observed that the i+1 th application is not being started even after i th application is completed. In such cases, if I press enter in the cygwin console on which the bash script is running, the next application starts running. Is it because of any issue with bash on cygwin? Or is it an issue with the Windows OS itself? Have any of you observed such an issue with bash + cygwin + Windows?
Thanks.
I think I have seen this before.
Instead of
somecommand
try
somecommand </dev/null
If that doesn't work, try
cmd /c somecommand
Or experiment with other redirections, e.g.
somecommand >/dev/null
Sounds like you may have a problem with your shell script encoding; DOS (and Windows) uses CR+LF line endings, whereas Linux uses LF endings. Try saving the file as LF.
What might also be going on:
When I was running Cygwin on a school laptop, I encountered a dramatic slowing of shell scripts vs. when they were running in a native Linux environment. This was especially apparent when running a configure script from GNU Autotools.
Check your path for slow drives. (From the Cygwin FAQ):
Why is Cygwin suddenly so slow?
If suddenly every command takes a very long time, then something is probably attempting to access a network share. You may have the obsolete //c notation in your PATH or startup files. Using //c means to contact the network server c, which will slow things down tremendously if it does not exist.
You might also want to check whether you have an antivirus program running. Antivirus programs tend to scan every single executable file as it is executed; this can cause problems for even simple shell scripts that run hundreds or even thousands of individual programs before they run their course.
This mailing list post outlines what is needed to pseudo-mount the main /usr/bin directory as cygexec. I'm not sure what that does, but I found it helped.
If you're running a configure script, try the -C option.
Hope this helps!
Occasionally, I'll get this behaviour because I have accidentally deleted the 'she-bang' at the top of the script, that is, deleted the #!/bin/bash on the first line of the script.
It's even more likely for this to happen when a parent shell script calls a child script that has the she-bang missing!
Hope this helps.
A bit of a long shot, but I have seen some similar behaviour previously.
In Windows 2000, if any program running in a command prompt window had some of it's text highlighted by the cursor, it would pause the command running, and you had to press enter or clear the highlighting to get the command prompt to continue executing.
As I said, bit of a long shot, but accidental mouse clicks could be your issue...
Install cygwin with unix style line breaks and forget weird problems like that.
Try saving your script as "the-properly-line-broken-style" for your cygwin. That is, use the style you specified under installation.
Here is some relevant information:
https://stackoverflow.com/a/7048200/657703

Resources