330

How do I pass the command line arguments to an alias? Here is a sample:

alias mkcd='mkdir $1; cd $1;'

But in this case the $xx is getting translated at the alias creating time and not at runtime. I have, however, created a workaround using a shell function (after googling a little) like below:

function mkcd(){
  mkdir $1
  cd $1
}

Just wanted to know if there is a way to make aliases that accept CL parameters.
BTW - I use 'bash' as my default shell.

1
  • 2
    O/T but about as an alternative to doing a mkcd function, you can write mkdir mydirectoryname && cd $_ Commented Jul 1, 2018 at 10:50

11 Answers 11

352

Just to reiterate what has been posted for other shells, in Bash the following works:

alias blah='function _blah(){ echo "First: $1"; echo "Second: $2"; };_blah'

Running the following:

blah one two

Gives the output below:

First: one
Second: two
Sign up to request clarification or add additional context in comments.

14 Comments

Great solution. Some questions from a bash novice: Does the function have to be named with an underscore (or differently at all) or is that just for readability? What is the purpose of the trailing ";_blah" in defining the function? Why does it not work when using double quotes in place of single quotes (the $1 is not interpreted correctly) even when doing something that does not require quotes around the $1? Thanks in advance for the advice. I have a working solution but always like to understand more on why it works.
@mynameispaulie The function can be named anything. I've used an an underscore prefix as it is a common trick to help prevent name collisions (ie another function with the same name)
@mynameispaulie The double quotes allow Bash to replace $1 and $2 with the parameters passed to the function. Single quotes tell Bash not to do this.
I see this alias/function combo copy/pasted a lot, but it does not seem to serve any useful purpose. The standard approach would be to define the function once, with a sane name, and not have an alias.
I fail to see how this is preferred over function blah(){ echo "First: $1"; echo "Second: $2"; }
|
185

You found the way: create a function instead of an alias. The C shell has a mechanism for doing arguments to aliases, but bash and the Korn shell don't, because the function mechanism is more flexible and offers the same capability.

3 Comments

You however don't need functions when creating aliases in .bashrc file. For example # create an alias that takes port-number by the user alias serve="python -m SimpleHTTPServer $1" After making the change in the .bashrc file, make sure you enter the following command. ~$ source .bashrc You should be able to use this like so ~$ serve 8998
@kaizer1v, My observation on CentOS7.3 bash version 4.2.46 is that your suggestion doesn't work as you think it does. Because you are using double quotes the $1 is actually being evaluated to an empty string and the alias is actually the same as alias serve="python -m SimpleHTTPServer" and so whatever you pass after that alias is ALSO passed on the command line. If you try this set -x; alias serve="python -m SimpleHTTPServer $1 &" you will see the error/problem. Both your argument and the alias command are run as separate commands.
Functions do NOT offer the same capability as aliases. Aliases can be generated inside of a code block and affect surrounding structures (breaking from a while loop, starting a do block but not ending it, etc). I use this mechanism extensively to support elegant exception handling and trace logging in bash that could never be done with functions. Alias needs to be able to take parameters also to fully unlock it's potential.
61

You cannot in ksh, but you can in csh.

alias mkcd 'mkdir \!^; cd \!^1'

In ksh, function is the way to go. But if you really really wanted to use alias:

alias mkcd='_(){ mkdir $1; cd $1; }; _'

3 Comments

As an interesting side note, I think that the remote code execution vulnerability that everybody's been talking about recently involves doing almost exactly this same thing, but in an environment variable being set by raw user input. openwall.com/lists/oss-security/2014/09/24/11
@Floegipoky - Because its in an alias and not an env var, its substantially different. The ShellShock issues is that it runs when the env var is set. Setting an env var is supposed to be a safe operation. No script executes when the above alias is set, only when the alias is run.
Perhaps it should be pointed out that csh is usually not what a modern person should want to use. The alias-which-creates-a-function-then-executes-that-function indirection is relatively popular, but offers no benefit over a proper function as far as I can tell. (The function should properly quote its argument, anyway.) Downvoting.
19

To quote the bash man page:

There is no mechanism for using arguments in the replacement text. If arguments are needed, a shell function should be used (see FUNCTIONS below).

So it looks like you've answered your own question -- use a function instead of an alias

Comments

14

You may also find this command useful:

mkdir dirname && cd $_

where dirname is the name of the directory you want to create

1 Comment

@StarDust $_ is the output of the last command unix.stackexchange.com/a/271693/169772
7

The easiest way, is to use function not alias. you can still call a function at any time from the cli. In bash, you can just add function name() { command } it loads the same as an alias.

function mkcd() { mkdir $1; cd $1 ;}

Not sure about other shells

1 Comment

The function keyword is permitted by Bash (and Ksh) but doesn't really serve any useful purpose here. The portable syntax is simply mkcd () { mkdir "$1"; cd "$1"; } (notice also the fixed quoting).
4

I found that functions cannot be written in ~/.cshrc file. Here in alias which takes arguments

for example, arguments passed to 'find' command

alias fl "find . -name '\!:1'"     
Ex: >fl abc

where abc is the argument passed as !:1

2 Comments

That's not useful for the OP, whose default shell is bash. And Sanjaya R's answer mentioned csh aliases 4 years ago.
Sanjaya R's answer didn't explain what !:1 meant. I had to scroll down to see here that it was the argument. A good answer doesn't leave more questions, even if it wasn't for the OPs shell type.
2

You actually can't do what you want with Bash aliases, since aliases are static. Instead, use the function you have created.

Look here for more information: http://www.mactips.org/archives/2008/01/01/increase-productivity-with-bash-aliases-and-functions/. (Yes I know it's mactips.org, but it's about Bash, so don't worry.)

Comments

1

This works in ksh:

$ alias -x mkcd="mkdir \$dirname; cd \$dirname;"
$ alias mkcd
mkcd='mkdir $dirname; cd $dirname;'
$ dirname=aaa 
$ pwd
/tmp   
$ mkcd
$ pwd
/tmp/aaa

The "-x" option make the alias "exported" - alias is visible in subshells.

And be aware of fact that aliases defined in a script are not visible in that script (because aliases are expanded when a script is loaded, not when a line is interpreted). This can be solved with executing another script file in same shell (using dot).

Comments

-5

Here's a simple example function using Python. You can stick in ~/.bashrc.

You need to have a space after the first left curly bracket.

The python command needs to be in double quotes to get the variable substitution. Don't forget that semicolon at the end.

count(){ python -c "for num in xrange($1):print num";}

Example run:

$ count 6
0
1
2
3
4
5
$

3 Comments

In modern Python, you want range instead of xrange. But there is no need for Python here; just printf '%s\n' {0..5} or for ((i=0; i<$1; ++i)) do; echo "$i"; done if you want to use a variable for the end of the range.
My post didn't answer the question, but it was supposed to just be a simple example that creates a function at the command line, uses Python, and takes an argument.
Interpolating into a double-quoted string is brittle at best; perhaps better then to write a Python script which reads the argument from sys.argv[1] ... but again, there is no particular reason to use Python (or Awk, or COBOL, or Smalltalk, or C) here.
-6

An empty alias will execute its args:

alias DEBUG=

1 Comment

I see by your rep that you are new to SO (Stack Overflow). Please don't be dismayed by the voting down of your answer. It has been voted down because it really doesn't answer the question that the OP (Original Poster) asked to have answered. Hang in their and keep trying. Also when answering, try to include a simple example of how your answer works and show the output. This will help others see how your answer works.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.