For bash script, I can use "$@" to access arguments. What's the equivalent when I use an alias?

up vote 41 down vote accepted

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:

my_program_wrapper() {
    local first_arg="$1" \
          second_arg="$2"

    shift 2               # get rid of the first two arguments

    # ...

    /path/to/my_program "$@"
}
  • 3
    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? – ephemient Nov 5 '10 at 1:51
  • 2
    @ephemient Very true. I mean besides the fact that everyone uses GNU Bash and not the barebones POSIX shell. – amphetamachine Nov 5 '10 at 12:53

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

lsswp /tmp/

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 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 Feb 9 '16 at 23:40
  • 1
    @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. – Warren Young Feb 9 '16 at 23:44

Alias solution

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.

  • Humm? wrap_args x y z gives me: bash: syntax error near unexpected token `(' – Eliptical view Dec 15 '17 at 19:45
  • @Elipticalview Hmm, copy paste issue? Confirmed working on bash 4.4.12. – Tom Hale Dec 16 '17 at 16:14
  • 1
    I had f aliased. Once I unaliased f it works fine. The old name collision thing. – Eliptical view Dec 19 '17 at 3:51
  • command type f :) – Tom Hale Jun 25 at 16:56

I'm answering for csh:

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.

Example of use:

    $ 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

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.