1

I'm trying to make an alias in the bashrc file but having issues. I want the command to grep the access logs of our server for a particular IP address. My current entry is:

alias ip_usage='sudo grep "$1" /srv/logs/httpd/chris-server.com/access.log'

My shell usage is:

ip_usage 192.168.0.0

but this brings back all records in the access log.

I also tried inverting the quote usage but the performance was the same.

alias ip_usage="sudo grep '$1' /srv/logs/httpd/chris-server.com/access.log"

Running:

sudo grep '192.168.0.0' /srv/logs/httpd/chris-server.com/access.log

brings my back the records I want so it is something with my quotes and the value being passed in.

2
  • 2
    This sounds like something better suited to place into a function than an alias.
    – DopeGhoti
    Commented Nov 17, 2017 at 21:16
  • @DopeGhoti You were correct, a function was the correct route.
    – user116042
    Commented Nov 17, 2017 at 21:28

1 Answer 1

5

The first version of the quoting would be correct except that aliases don't do what you want. You need a function:

ip_usage() { sudo grep "$1" /srv/logs/httpd/chris-server.com/access.log; }

Documentation

From man bash:

Aliases allow a string to be substituted for a word when it is used as the first word of a simple command.

In other words, aliases do string substitution. They do not support manipulation of arguments. Thus, referencing a first argument inside an alias via $1 is not supported.

Also from man bash:

A shell function, defined as described above under SHELL GRAMMAR, stores a series of commands for later execution. When the name of a shell function is used as a simple command name, the list of commands associated with that function name is executed. Functions are executed in the context of the current shell; no new process is created to interpret them (contrast this with the execution of a shell script). When a function is executed, the arguments to the function become the positional parameters during its execution. The special parameter # is updated to reflect the change. Special parameter 0 is unchanged. The first element of the FUNCNAME variable is set to the name of the function while the function is executing.

In other words, bash functions do support positional arguments.

Aside: Why an alias with $1 at the end might seem to work

Let's define an alias

$ alias e='echo $1'

Now, let's clear the shell's positional argument and run the alias:

$ set -- 
$ e a b c
a b c

It does what one might hope.

Notice, though, that there is a trap. Let's set the shell's first positional argument:

$ set -- First
$ echo "$1"
First

Now, let's run our command again:

$ e a b c
First a b c

Here, it is clear that $1 in an alias refers to the first shell's first argument, not the aliases first argument.

3
  • Strange, I have alias svn_diff='svn diff --diff-cmd /usr/bin/diff -x "-i -b" $1' working, where $1 is a file path. I have confirmed this works for the ip_usage. I'm not following the difference between functions and aliases. It seems like the above example uses positional arguments.
    – user116042
    Commented Nov 17, 2017 at 21:22
  • 1
    @chris85 Yes, that works but only accident because the $1 is at the end of the alias where the arguments you supply would appear (with or without the $1 at the end).
    – John1024
    Commented Nov 17, 2017 at 21:24
  • 1
    @chris85 Very good. Also, I just added a longer explanation to the answer of how aliases work with $1.
    – John1024
    Commented Nov 17, 2017 at 21:31

You must log in to answer this question.