Converting an old .cshrc file into a .bash_aliases file. I've run into a few syntax issues regarding the conversion, but this involves a little more in depth knowledge of Bash.

In [t]Csh, the shell would hang when opening xwindow applications, unless they were opened in the background using an ampersand (e.g., firefox &). To avoid this, I would create certain aliases in Csh to run the task in the background, but still leave the command line open for options (using \!*):

alias ff 'firefox \!* &

When this is converted to Bash it'll do something like this:

ff () { command ff "$@" & }

I still am not sure when to use a function and when to use alias, but I came into a predicament when trying to wrap more options around an already defined alias:

win () { command xterm -geometry 105x25 -font 8x13 -bc "$@" & }
blue () { command win -bg gray33 -fg gray39 "$@" ; }

If I remove the command within blue (e.g., blue () { win -bg ...) it works as expected.

So I'm curious about two things:

  1. When to use alias vs function definitions?
  2. When to use command; if I did alias win='xterm ...' would I have to do command win then?

One, use functions for anything non-trivial; a trivial alias would be to set some flag by default:

# no license spam
alias gdb='gdb -q'

for pretty much anything more complicated I use a function.

Two, command refers to a command, such as /bin/ls or the like; aliases are not commands, nor are functions commands. You likely have no win command, so command win will fail to call the function, as that is not a command.

"Infinite" loops are really easy to create, by the way

alias fooalias=foofunc
function foofunc() { fooalias; }

which is why if one is writing a function with the same name as a command then command becomes really handy so the shell doesn't attempt to call the function forever:

# loops until stack death or segfault or something
function xterm() { xterm ... }

# good
function xterm() { command xterm ... }

If you're just trying to get some other function to call something else that may be a command or function, just call it as is. The one that does need to call the command must use command.

function winwinwin () { winwin ... }
function winwin () { win ... }
function win () { xterm ... }
function xterm () { command xterm ... }

winwinwin would call the winwin function would call the win function would call the xterm function and then that would instead call the named command.

On the function front, that is optional, but I use it as it makes searching for functions rather easy (fgrep function ...) than having to look for things followed by maybe whitespace and err umm do parens need to be escaped in the regex engine I'm using? For the priority, it's easy to make tests or print notices that show what is happening:

ls () { ls -k; echo funcall; }
alias ls='echo blat'

In general it's probably a better idea to define functions first, and aliases after those are setup, for least surprise:

bash-4.1$ alias ls='echo blat'
bash-4.1$ ls () { command ls -k; echo funcall; }
bash: syntax error near unexpected token `('
bash-4.1$ function ls () { command ls -k; echo funcall; }
  • I probably have years of bad habits and set-it-and-forget-it resource files -- bad me. Is the function necessary? I typically do func_name () { ... }; here I'm at the mercy of the syntax that the conversion script (cshtobash) implements. I suspect aliases and functions have different implementation schemes, so I'm curious if using an alias might even save an op or two. – BotNet Oct 6 '16 at 22:02
  • I don't like to comments with questions. But one quick follow up before I select your answer... Let's say I alias ls='ls -h' and later, in a nested resource wanted to wrap that with whatever, ls () { ls -k ; }, this would error unless the function keyword is used (function ls (){...}) -- I'm curious if that's because ls is a command and that might be trying to execute ls instead of defining it? – BotNet Oct 6 '16 at 22:09
  • Giving that more thought, I think function ls () { ls ... } would result in an infinite loop, as you pointed out. – BotNet Oct 6 '16 at 22:24
  • It would be, that's why function ls () { command ls ... } is needed in this case. Interesting, though, calling command in the function is not calling the /bin/ls, but instead the alias – BotNet Oct 6 '16 at 22:35

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.