47

I know how to configure aliases in bash, but is there a way to configure an alias for a sequence of commands?

I.e say I want one command to change to a particular directory, then run another command.

In addition, is there a way to setup a command that runs "sudo mycommand", then enters the password? In the MS-DOS days I'd be looking for a .bat file but I'm unsure of the linux (or in this case Mac OSX) equivalent.

Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
stormist
  • 5,709
  • 12
  • 46
  • 65

8 Answers8

99

For chaining a sequence of commands, try this:

alias x='command1;command2;command3;'

Or you can do this:

alias x='command1 && command2 && command3'

The && makes it only execute subsequent commands if the previous returns successful.

Also for entering passwords interactively, or interfacing with other programs like that, check out expect. (http://expect.nist.gov/)

Larry Shatzer
  • 3,579
  • 8
  • 29
  • 36
  • It's been a while since I've done this, but I think the first suggestion will result in the 3 commands being executed in parallel (or as much as possible), and the second will have the 3 commands exected serially. Either way, I'm not sure they do the same thing. – FrustratedWithFormsDesigner Jan 25 '10 at 21:17
  • I just tried it with alias x='date;sleep 1;date' And the output is what I expect (two dates, 1 second apart), with the sleep delay between each date output. – Larry Shatzer Jan 25 '10 at 21:20
  • 11
    @Frustrated: No. Both executed in serial. Only the first doesn't care if a previous command fail. To execute in parallel would be: `command1 & command2 & command3` – slebetman Jan 25 '10 at 21:29
  • Any idea how to make this work with a wildcard? Say, I want to delete my local stage branch on git whenever I check out of it in to my feature branch. – riders994 Apr 18 '19 at 18:47
  • What about x arguments? – Sosukodo Apr 26 '19 at 14:52
  • If you want arguments to an alias, you need to write a function. See https://stackoverflow.com/questions/7131670/make-a-bash-alias-that-takes-a-parameter – Larry Shatzer Apr 26 '19 at 16:44
20

You mention BAT files so perhaps what you want is to write a shell script. If so then just enter the commands you want line-by-line into a file like so:

command1
command2

and ask bash to execute the file:

bash myscript.sh

If you want to be able to invoke the script directly without typing "bash" then add the following line as the first line of the file:

#! /bin/bash
command1
command2

Then mark the file as executable:

chmod 755 myscript.sh

Now you can run it just like any other executable:

./myscript.sh

Note that unix doesn't really care about file extensions. You can simply name the file "myscript" without the ".sh" extension if you like. It's that special first line that is important. For example, if you want to write your script in the Perl programming language instead of bash the first line would be:

#! /usr/bin/perl

That first line tells your shell what interpreter to invoke to execute your script.

Also, if you now copy your script into one of the directories listed in the $PATH environment variable then you can call it from anywhere by simply typing its file name:

myscript.sh

Even tab-completion works. Which is why I usually include a ~/bin directory in my $PATH so that I can easily install personal scripts. And best of all, once you have a bunch of personal scripts that you are used to having you can easily port them to any new unix machine by copying your personal ~/bin directory.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • 2
    You can also use a shell function `myfunc() { command1 && command2}` if you don't want to litter the place with files. – Noufal Ibrahim Jan 25 '10 at 21:27
  • 2
    But "littering the place with files" is less messy compared to littering the .bashrc file with functions. Think modular :-) – slebetman Jan 25 '10 at 21:34
  • What language are shell scripts written in? – stormist Jan 26 '10 at 15:49
  • 4
    Believe it or not, the shell you're typing on is not merely a "command prompt" but a full, turing-complete programming language (albeit one with horrible syntax). So shell scripts are written in the language of the shell. And there are several shells available in unixland: sh (the classic bourne shell), bash (bourne-again shell evolved from sh), csh (the classic c shell), tcsh (evolved from csh), ksh (korn shell) .. there are several others but these are the most common. On Linux these days most write shell scripts with bash. – slebetman Jan 26 '10 at 16:18
  • 1
    Note that it is not necessary to write shell scripts in the language of the shell you use in your terminal since the shbang line allows you to specify under which shell the script runs. It is only necessary to have the shell you use to write scripts in installed on the machine. – slebetman Jan 26 '10 at 16:20
  • Other scripting languages like Tcl, Perl, Python, Ruby and Lua simply make use of the shbang mechanism to implement executable scripts. The difference between "proper" scripting languages and shells is that it is generally not practical to use a scripting language as a command interpreter - they have too much syntax! – slebetman Jan 26 '10 at 16:26
  • Note: You should have noticed from the other answers that you can write functions in your shell - a hint that the shell is actually a programming language. – slebetman Jan 26 '10 at 16:30
10

it's probably easier to define functions for these types of things than aliases, keeps things more readable if you want to do more than a command or two:

In your .bashrc

perform_my_command() {
    pushd /some_dir
    my_command "$@"
    popd
}

Then on the command line you can simply do:

perform_my_command my_parameter my_other_parameter "my quoted parameter"

You could do anything you like in a function, call other functions, etc.

You may want to have a look at the Advanced Bash Scripting Guide for in depth knowledge.

wich
  • 16,709
  • 6
  • 47
  • 72
8

For the alias you can use this:

alias sequence='command1 -args; command2 -args;'

or if the second command must be executed only if the first one succeeds use:

alias sequence='command1 -args && command2 -args'
gregseth
  • 12,952
  • 15
  • 63
  • 96
6

Your best bet is probably a shell function instead of an alias if the logic becomes more complex or if you need to add parameters (though bash supports aliases parameters).

This function can be defined in your .profile or .bashrc. The subshell is to avoid changing your working directory.

function myfunc {
   ( cd /tmp; command )
}

then from your command prompt

$ myfunc

For your second question you can just add your command to /etc/sudoers (if you are completely sure of what you are doing)

myuser           ALL = NOPASSWD: \
                    /bin/mycommand 
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
5

Apropos multiple commands in a single alias, you can use one of the logical operators to combine them. Here's one to switch to a directory and do an ls on it

      alias x="cd /tmp && ls -al"

Another option is to use a shell function. These are sh/zsh/bash commands. I don't know enough of other shells to be sure if they work.

As for the sudo thing, if you want that (although I don't think it's a good idea), the right way to go is to alter the /etc/sudoers file to get what you want.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
4

You can embed the function declaration followed by the function in the alias itself, like so:

alias my_alias='f() { do_stuff_with "$@" (arguments)" ...; }; f'

The benefit of this approach over just declaring the function by itself is that you can have a peace of mind that your function is not going to be overriden by some other script you're sourcing (or using .), which might use its own helper under the same name.

E.g., Suppose you have a script init-my-workspace.sh that you're calling like . init-my-workspace.sh or source init-my-workspace.sh whose purpose is to set or export a bunch of environment variables (e.g., JAVA_HOME, PYTHON_PATH etc.). If you happen to have a function my_alias inside there, as well, then you're out of luck as the latest function declaration withing the same shell instance wins.

Conversely, aliases have separate namespace and even in case of name clash, they are looked up first. Therefore, for customization relevant to interactive usage, you should only ever use aliases.

Finally, note that the practice of putting all the aliases in the same place (e.g., ~/.bash_aliases) enables you to easily spot any name clashes.

eold
  • 5,972
  • 11
  • 56
  • 75
1

you can also write a shell function; example for " cd " and "ls " combo here

Community
  • 1
  • 1
B.Kocis
  • 1,954
  • 20
  • 19