Bash – Troubleshooting Alias or Function Issues

aliasbashfunction

When I create

alias wd='ps -ef | grep java | awk {'print $2 " " $9'} | egrep "(A|B|C|D)"'

or

function wd () {
    ps -ef | grep java | awk '{print $2}' ...
}

in my .bashrc file, I get errors. Interestingly, if I source my .bashrc file with the function, it 'compiles', but when executing, gives me:

 context is
     >>> \ <<< {\print
    missing }

Can someone help me with this, and also answer when its better to put something in a function versus in an alias?

Best Answer

Why the alias doesn't work

alias wd='ps -ef | grep java | awk {'print $2 " " $9'} | egrep "(A|B|C|D)"'

The alias command receives three arguments. The first is the string wd=ps -ef | grep java | awk {print (the single quotes prevent the characters between them from having a special meaning). The second argument consists of a single space character. (In .bashrc, the positional parameters $2 and $9 are empty, so $2 expands to a list of 0 words.) The third argument is } | egrep "(A|B|C|D)" (again the single quotes protect the special characters).

The alias definition is parsed like any other shell command when it is encountered. Then the string defined for the alias is parsed when the alias is expanded. Here are some possible ways to define this alias. First possibility: since the whole alias definition is within single quotes, only use double quotes in the commands, which means you must protect the " and $ meant for awk with backslashes.

alias wd='ps -ef | grep java | awk "{print \$2 \" \" \$9}" | egrep "(A|B|C|D)"'

Second possibility: every character stands for itself within single quotes, except that a single quote ends the literal string. '\'' is an idiom for “single quote inside a single-quoted string”: end the single-quoted string, put a literal single quote, and immediately start a new single-quoted string. Since there's no intervening space, it's still the same word.

alias wd='ps -ef | grep java | awk '\''{print $2 " " $9}'\'' | egrep "(A|B|C|D)"'

You can simplify this a bit:

alias wd='ps -ef | grep java | awk '\''{print $2, $9}'\'' | egrep "(A|B|C|D)"'

Tip: use set -x to see how the shell is expanding your commands.

Why the function doesn't work

I don't know. The part you show looks ok. If you still don't understand why your function isn't working after my explanations, copy-paste your code.

Alias or function?

Use an alias only for very simple things, typically to give a shorter name to a frequently-used command or provide default options. Examples:

alias grep='grep --color'
alias cp='cp -i'
alias j=jobs

For anything more complicated, use functions.

What you should have written

Instead of parsing the ps output, make it generate output that suits you.

wd () {
  ps -C java -o pid=,cmd= | egrep "(A|B|C|D)"
}
Related Question