- How to pass parameters to an alias?
- Can I pass arguments to an alias command?
- 4 Answers 4
- Working around alias limitations with group command and here-string
- But is this good approach ?
- bash alias with parameters [duplicate]
- 1 Answer 1
- How to pass command line arguments to a shell alias? [duplicate]
- 11 Answers 11
How to pass parameters to an alias?
If you’re really against using a function per se, you can use:
$ alias wrap_args='f()< echo before "$@" after; unset -f f; >; f' $ wrap_args x y z before x y z after
You can replace $@ with $1 if you only want the first argument.
Explanation
This creates a temporary function f , which is passed the arguments.
Alias arguments are only passed at the end. Note that f is called at the very end of the alias.
The unset -f removes the function definition as the alias is executed so it doesn’t hang around afterwards.
This is great for special cases. Consider a block of code where you want to prevent echo with minimal fuss: alias echo=’f()< echo "$@" &>/dev/null; unset -f f; >; f’ . For example, adding that one line to a boot script to force a quiet mode.
This looks like a useless complication that still has many of the downsides of an alias, like the quoting hell that comes up if the function code itself needs to use single-quoted strings. Just defining the function the usual way wouldn’t suffer that problem, and wrap_args()< echo before "$@" after; >; would be shorter to boot, and there wouldn’t be name clashes with the temporary function.
Aliases are like commands in that all arguments to them are passed as arguments to the program they alias. For instance, if you were to alias ls to ls -la , then typing ls foo bar would really execute ls -la foo bar on the command line.
If you want to have actual control over how the arguments are interpreted, then you could write a function like so:
opengroup.org/onlinepubs/009695399/utilities/… Functions in sh are defined my_program_wrapper() < . ; >. Bash does handle the keyword function but why not go with what’s more portable?
@SridharSarnobat If by export you mean export -f my_program_wrapper see this question for an explanation, then the answer is no; you will want to add the function to ~/.bashrc in order to have it usable in interactive shells.
Adding to the present answers, an important thing to realize about how aliases work is that all the parameters you type after an aliased command will be used literally at the end. So there is no way to use alias for two commands (piped or not), out of which the first should interpret the parameters. To make it clear, here’s an example of something that would not work as expected:
alias lsswp="ls -l | grep swp"
(an example inspired by this question) this will always use the output of ls -l performed in the current directory and do a grep on that — so using
would be equivalent to ls -l | grep swp /tmp/ and not ls -l /tmp/ | grep swp .
For all purposes where the arguments should be used somewhere in the middle, one needs to use a function instead of an alias.
You don’t have to do anything, actually; aliases do this automatically. For instance:
$ alias less="less -eirqM" $ less foo.txt
You will see foo.txt’s first page, and less will quit at EOF (-e), searches will be case-insensitive (-i), etc.
Can you please look at my question — none of the solutions works for me and I am not allowed start a bounty.
@JJD The one who answered your question is correct: you want a function in that case, not an alias. Since the accepted answer to this question is essentially the same, your question was rightly closed.
Yes, you can use the parameters in aliases and — as a difference to what has been said above — you can refer to them anywhere in the definition of alias — not only at the end.
Example for tar-gz -ing something:
$ alias tgz "tar cvf - \!:1 | gzip -9 > \!:2.tar.gz"
, where !:1 and !:2 are the parameters you will supply when calling your alias.
$ ls clrcf.dat user_comment_2016.06.03_12:51:50.txt user_comment_2016.06.03_12:54:48.txt TEST-wADM.tec user_comment_2016.06.03_12:52:04.txt user_comment_2016.06.03_12:55:13.txt $ tgz user* out a user_comment_2016.06.03_12:51:50.txt 1K a user_comment_2016.06.03_12:52:04.txt 1K a user_comment_2016.06.03_12:54:48.txt 1K a user_comment_2016.06.03_12:55:13.txt 1K $ ls out* out.tar.gz
Which effectively means that you used two parameters that you inserted at arbitrary places of the tar command, making of all of it an alias tgz
Can I pass arguments to an alias command?
Now d will print the last 5 lines. If I want to use d to print a different number of lines, I have to make change in the alias command declaration of d again. Is there any way I can modify the declaration of an alias so that I don’t have to retype the declaration to change the number of lines. Like incorporating passing the number of lines as an argument while declaring alias for d ? Or is there some other method to solve this?
In (t)csh, «\!*» references arguments to an alias (the backslash is just to escape the exclamation mark which normally means «history»), and you can even reference individual arguments, though I don’t remember how. So perhaps «tail -n \!*» or something (I don’t think \!* will work with a minus sign immediately before it). However, not sure if this will work in (ba)sh.
4 Answers 4
Aliases don’t take arguments. With an alias like alias foo=’bar $1′ , the $1 will be expanded by the shell to the shell’s first argument (which is likely nothing) when the alias is run.
So: Use functions, instead.
d () < num=$dmesg |grep -iw usb|tail -$num >
num=$ uses the first argument, with a default value of 5 if it isn’t provided.
$ d # prints 5 lines $ d 10 # prints 10 lines
Or, if you change the options you used slightly:
alias d="dmesg|grep -iw usb|tail -n 5"
Then you can pass additional -n options:
$ d # prints 5 lines $ d -n 10 # prints 10 lines
If multiple -n options are specified for tail , only the last is used.
For the functionally challenged like myself 🙂 it might be helpful to briefly state where to put the function. ie ~/.bashrc or rc.local or wherever?
You need to have a function for this as described in the SO and here. Try the following:
Working around alias limitations with group command and here-string
Aliases can’t take arguments, but we can «simulate» that. Take for instance example of my answer on this question.
Key points that are happening here:
- we use read built in to read a string into a variable d . Because we want to read a full string including blank characters(newline’s,tabs,spaces), we use IFS= and disable back backslash escapes with -r .
- multiple commands within alias are combined and executed in current shell using < list; >structure (which is known as group command in the bash manual). Note that leading space after < and ; individual list of commands are required.
In your specific example we could do:
We could also make use of word splitting to store space-separated arguments:
Or we could use arrays to provide multiple arguments:
But is this good approach ?
Not necessarily. The problem with such approach is that it’s very specific — arguments can’t be quoted easily which means we can only have arguments with no spaces.
This is of course not something that would be widely used, simply because in the real world we have to deal with complex arguments, so this approach isn’t quite practical. Functions are far more flexible. And the need to quote args string becomes annoying fast.
Despite the limitations, this works with simple strings as arguments where we can afford word splitting, thus partially allows us to give arguments to aliases.
bash alias with parameters [duplicate]
I would like to swap from csh to bash, then I have to set the .bashrc with the commands I use. Translating alias with parameters seems to be not easier as I believed. csh:
alias gr 'xmgrace -legend load -nxy \!* -free -noask&'
alias gr='xmgrace -legend load -nxy $@ -free -noask&' alias gr='xmgrace -legend load -nxy $(@) -free -noask&'
alias t 'set t=\`pwd\``;echo $t' alias tt 'cd $t'
@muru I was looking for a suitable dupe but couldn’t find one..the answer from the one you have referred to does not provide the whole scenario IMHO..
@muru well, i have tried to make it more clarified. if you don’t feel the same its allright..i thought i should tell you what i felt prior to answering, nothing more 🙂
1 Answer 1
This is not the way bash aliases work, all the positional parameters in the bash aliases are appended at the end of the command rather than the place you have defined. To get over it you need to use bash functions.
An example will make you more clear :
$ cat file.txt foo $ cat bar.txt foobar spamegg $ grep -f file.txt bar.txt foobar $ alias foo='grep -f "$1" bar.txt' ## Alias 'foo' $ foo file.txt grep: : No such file or directory $ spam () < grep -f "$1" bar.txt ;>## Function 'spam' $ spam file.txt foobar
As you can see as the first argument in case of alias foo is being added at the end so the command foo file.txt is being expanded to :
while in case of function spam the command is correctly being expanded to :
So in your case, you can define a function like :
How to pass command line arguments to a shell alias? [duplicate]
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:
Just wanted to know if there is a way to make aliases that accept CL parameters.
BTW — I use ‘bash’ as my default shell.
O/T but about as an alternative to doing a mkcd function, you can write mkdir mydirectoryname && cd $_
11 Answers 11
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'
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.
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.
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.