I have a command I am trying to alias for simplicity:

php artisan route:list | (head -n 3; grep checkout)

This command shows me the header of this table and searches for the route. The result looks like this:

| Domain | Method   | URI                                        | Name                                               | Action                                                                        | Middleware                                           |
|        | POST     | profile/auctions/checkout                  | user-portal-profile-auctions-checkout              | xxxxxxxxxxxxxxxx                   | web,auth                                             |
|        | POST     | profile/deals/checkout                     | user-portal-profile-deals-checkout                 | xxxxxxxxxxxxxx                     | web,auth                                             |
|        | POST     | profile/quotes/checkout                    | user-portal-profile-quotes-checkout                | xxxxxxxxxxxxxxx                    | web,auth                                             |

So this is what I have in my ~/.bash_profile:

alias findRoute='php artisan route:list | (head -n 3; grep $1)'

But I keep getting this error:

bash: syntax error near unexpected token `checkout'

What gives? Why will it not accept my argument?

I have tried using single and double quotes in the argument I pass.

I have tried using single and double quotes in the alias. Nothing changes.


Alias expansion is just text replacement followed by another round of parsing by the shell.

When you enter

findRoute checkout

That's first expanded to:

php artisan route:list | (head -n 3; grep $1) checkout

And that result is again parsed as shell code. That's invalid shell code here.

You'd want to use a script or function instead here. Like:

findRoute() {
  php artisan route:list | {
    head -n 3
    grep -e "$1"

Now, beware that head may read more than 3 lines, even though it outputs only 3 as most head implementations read by entire blocks. That means grep would not get to see that part.

If your sed is the GNU implementation, you can replace head -n3 with sed -u 3q, where sed reads the input one byte at a time so as not read past the third newline characters.

Alternatively, you could use awk instead as:

findRoute() {
  php artisan route:list |
    PATTERN=$1 awk 'NR <= 3 || $0 ~ ENVIRON["PATTERN"]'

Beware $1 is then interpreted as an extended regular expression (like for grep -E) instead of a basic one (with grep without -E). For a substring search (as in grep -F), replace with:

findRoute() {
  php artisan route:list |
    PATTERN=$1 awk 'NR <= 3 || index($0, ENVIRON["PATTERN"])'
  • Wow. Okay that makes sense because of the ()'s. So if I wasn't using head and ended with grep $1 it would take my argument. – Goahnary Feb 26 '20 at 22:51
  • No. I am still wrong. Aliasing is just text replacement like you said. I would need to use a function. Otherwise, the argument just gets tacked on to the end. – Goahnary Feb 26 '20 at 22:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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