9

I am writing a bash script that runs each of its arguments as a command. This works for commands in my PATH, but not for aliases. I can directly call an alias in the script, but I can't call an alias that has been passed as an argument.

The problem (I assume) is that aliases are expanded before variables. Is there a way to run aliases from a variable?

Sample script:

#!/bin/bash
# File: runall

shopt -s expand_aliases
source ~/.aliases

while (( "$#" )); do
    $1
    shift
done

runall "echo test" works, but runall "myalias" gives runall: line 8: myalias: command not found

9

After some testing, I have concluded the following:

  • Aliases only work in interactive mode (add -i to the shebang).
  • Aliases are not evaluated when they come from an interpreted source (in this case, the variable.
  • You can get bash to use the alias with eval $1. Note that evaling anything created with a variable is dangerous, but since the whole point of the script requires arbitrary execution, I won't make too big a deal out of that.

From the bash man page:

Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS below).

So you could add shopt -s expand_aliases instead of -i.

Also,

Aliases are expanded when a command is read, not when it is executed.

Since variables are not expanded before the command is read, they will not be expanded further using the alias.

  • 1
    Nice to know. Just out of curiosity: why is it dangerous to eval variables? – user13742 Feb 15 '12 at 18:13
  • 1
    @hesse Consider eval "echo $1". Say I call ./script.sh "hello;rm -rf ~. What gets executed? echo hello, followed by rm -rf ~. Obviously that's a contrived example, but the principle holds. – Kevin Feb 15 '12 at 18:18
  • adding eval in front of $1 worked, since I already had shopt -s expand_aliases. Thanks! – Jayson Feb 15 '12 at 22:13
1

I had a similar problem and managed to solve my issue by turning my aliases to functions, as described on this site, which worked for me.

e.g.

alias lsd="ls -lash"

to

function lsd() { ls -lash; }

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.