140

Is it possible to do the following:

I want to run the following:

mongodb bin/mongod

In my bash_profile I have

alias = "./path/to/mongodb/$1"
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
slik
  • 5,001
  • 6
  • 34
  • 40

6 Answers6

249

An alias will expand to the string it represents. Anything after the alias will appear after its expansion without needing to be or able to be passed as explicit arguments (e.g. $1).

$ alias foo='/path/to/bar'
$ foo some args

will get expanded to

$ /path/to/bar some args

If you want to use explicit arguments, you'll need to use a function

$ foo () { /path/to/bar "$@" fixed args; }
$ foo abc 123

will be executed as if you had done

$ /path/to/bar abc 123 fixed args

To undefine an alias:

unalias foo

To undefine a function:

unset -f foo

To see the type and definition (for each defined alias, keyword, function, builtin or executable file):

type -a foo

Or type only (for the highest precedence occurrence):

type -t foo
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • 11
    Just want to add example from my .bashrc mkcd () { mkdir "$@" && cd "$@"; } where i'm creating dir and cd'ing into – Vova Lando Dec 30 '13 at 15:06
  • You should color "abc" red as well since $@ = list of arguments passed to the function. – thdoan Jul 07 '14 at 04:43
  • 4
    @10basetom: If you're referring to the colors in my answer, that's done automatically by the syntax highlighter. – Dennis Williamson Jul 07 '14 at 05:12
  • After adding function foo () {....} how do i remove it? – shinobi Jul 13 '16 at 11:18
  • 1
    @shinobi: `unset -f foo` – Dennis Williamson Jul 13 '16 at 15:24
  • What about if I want to get an output like this one: ´$ /path/to/bar/abc/123 fixed args´ ? How can I do that? – Mymozaaa Jul 19 '17 at 14:23
  • @Mymozaaa: It's not clear what you want to be able to do. Do you want to pass dirname and filename of the _executable_ as arguments? – Dennis Williamson Jul 19 '17 at 16:56
  • @DennisWilliamson Yes! Ultimately, I want to pass as an argument just the filename. I was told it wouldn't be possible in an alias, and that I should use a bash script instead. Is it correct? – Mymozaaa Jul 19 '17 at 17:30
  • I think you might want to add the directory of your executable to your `PATH`: `PATH=$PATH:/path/to/bar` then you can run an executable called `123` (and args) without specifying the directory. Or just specify the full directory (and args) `/path/to/bar/abc/123 fixed args` each time. Please see [BashFAQ/50](http://mywiki.wooledge.org/BashFAQ/050) for reasons why you shouldn't do what you think you want to do. – Dennis Williamson Jul 19 '17 at 23:01
  • You just need to declare a function in your `.bash_profile` or `.zshrc` without do anything else. For example: add line `foo() { echo $1 }` to your profile file, and then you can call `foo` directly in your shell. – acrazing Dec 17 '18 at 02:51
27

to use parameters in aliases, i use this method:

alias myalias='function __myalias() { echo "Hello $*"; unset -f __myalias; }; __myalias'

its a self-destructive function wrapped in an alias, so it pretty much is the best of both worlds, and doesnt take up an extra line(s) in your definitions... which i hate, oh yeah and if you need that return value, you'll have to store it before calling unset, and then return the value using the "return" keyword in that self destructive function there:

alias myalias='function __myalias() { echo "Hello $*"; myresult=$?; unset -f __myalias; return $myresult; }; __myalias'

so..

you could, if you need to have that variable in there

alias mongodb='function __mongodb() { ./path/to/mongodb/$1; unset -f __mongodb; }; __mongodb'

of course...

alias mongodb='./path/to/mongodb/'

would actually do the same thing without the need for parameters, but like i said, if you wanted or needed them for some reason (for example, you needed $2 instead of $1), you would need to use a wrapper like that. If it is bigger than one line you might consider just writing a function outright since it would become more of an eyesore as it grew larger. Functions are great since you get all the perks that functions give (see completion, traps, bind, etc for the goodies that functions can provide, in the bash manpage).

I hope that helps you out :)

osirisgothra
  • 2,163
  • 24
  • 19
  • 2
    ~$ alias myalias='function __myalias() { echo "Hello $*"; unset -f __myalias; } __myalias' ~$ myalias -bash: syntax error near unexpected token `__myalias' – JeeBee Nov 14 '13 at 14:34
  • This is horrible! you're redefining the function each time? (I can't even bother to check if you have syntax errors there). – gniourf_gniourf Apr 28 '14 at 20:23
  • 1
    It is not like they have to do it EXACTLY that way, it was supposed to be an example, and yes it is redefined each time, which keeps it at one line, otherwise, it wouldn't be a one-shot would it? That's like complaining that "alias" expands itself to it's assigned content every time, how is this any different? And there is no need to get so emotional. – osirisgothra May 02 '14 at 11:59
  • JeeBee: the line editor joined my lines together, so i put that ; in there to correct it – osirisgothra May 07 '14 at 16:36
23

Usually when I want to pass arguments to an alias in Bash, I use a combination of an alias and a function like this, for instance:

function __t2d {                                                                
         if [ "$1x" != 'x' ]; then                                              
            date -d "@$1"                                                       
         fi                                                                     
} 

alias t2d='__t2d'                                                               
leed25d
  • 643
  • 6
  • 13
  • 1
    What is that always-false `if` statement for? – Dennis Williamson Oct 30 '10 at 22:38
  • fixed. It was a typo, sorry. it was really meant to check for the existence of $1 – leed25d Oct 30 '10 at 22:48
  • 18
    `[ -n "$1" ]` (the use of "x" in that manner is archaic and unnecessary for any modern shell) – Dennis Williamson Oct 31 '10 at 01:37
  • 4
    Well, you can call me Old School. The original question dealt with aliases and arguments to them. I believe that your remark contributes nothing germane to the conversation. – leed25d Oct 31 '10 at 03:15
  • 21
    well its pretty good info though not to use the x, because it confuses newbies, which arrogant coders seem to enjoy doing for some reason. We are supposed to be helping here, and whether or not something is old school doesn't really excuse the confusion that it brings to the table. – osirisgothra Nov 02 '13 at 04:59
  • 4
    Good info would be to tell newbies not to do this at all, since it's completely pointless. What they want is just a function. Making a function and then aliasing that to another name is really completely pointless. – remmy Jul 24 '14 at 15:32
  • 9
    @leed25d Stupid question: if you write `__t2d` as a function, then why would you even want the alias? Why not name the function `t2d` and skip the alias? – Mark E. Haase Mar 12 '15 at 16:17
  • 2
    @MarkE.Haase I don't think there would ever be a good answer to that. All you have to do is look at the coding style to understand this person is writing code that belongs in 1978. 8 spaces for tabs? Double underscores for 'hidden' functions? The intention was probably to hide the implementation behind an alias that is free to change the underlying function call, but that's just stupid. – Anthony Dec 23 '18 at 17:46
  • @MarkE.Haase Only needed if you want to pass the arguments in the middle of the command. – Puvipavan Nov 09 '21 at 14:50
14

This is the solution which can avoid using function:

alias addone='{ num=$(cat -); echo "input: $num"; echo "result:$(($num+1))"; }<<<'

test result

addone 200
input: 200
result:201
blreay
  • 141
  • 1
  • 2
  • It worked perfectly for me. I wanted to pass the color number (from 31 to 37) to PS command in my alias. I did something like this: alias psany='{ PS1="\e[0;$(cat -)m> \e[m";}<<<' USAGE: psany 32 – zviad Nov 24 '17 at 16:26
  • This should be way higher! In my use-case, using a function wasn't viable, because I wanted `return` to fail if the script is not sourced. Wrapping the alias in a function meant `return` is always executed successfully. Thank you for the solution. I'll tip you in BCH if you provide a wallet. – Lubo Kanev Apr 11 '18 at 18:10
5

In csh (as opposed to bash) you can do exactly what you want.

alias print 'lpr \!^ -Pps5'
print memo.txt

The notation \!^ causes the argument to be inserted in the command at this point.

The ! character is preceeded by a \ to prevent it being interpreted as a history command.

You can also pass multiple arguments:

alias print 'lpr \!* -Pps5'
print part1.ps glossary.ps figure.ps

(Examples taken from http://unixhelp.ed.ac.uk/shell/alias_csh2.1.html .)

Matt
  • 756
  • 1
  • 9
  • 24
jimgug
  • 165
  • 3
  • 10
  • Just to add that there's a more cool things on csh: "\!$" refers to the last argument. "\!:1" to the first (same as "\!^"), "\!:2" to the second ... There is also even optional arguments! "\!:1*" prints out all the arguments starting from argument 1 till the last where even argument 1 is optional. If that argument doesn’t exist, the variable will be assigned a null value. – Kiteloopdesign Mar 13 '22 at 11:38
-3

To simplify leed25d's answer, use a combination of an alias and a function. For example:

function __GetIt {
    cp ./path/to/stuff/$* .
}

alias GetIt='__GetIt'
Schroeder
  • 742
  • 8
  • 19