13

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

0

2 Answers 2

12

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.

3
  • 1
    Nice to know. Just out of curiosity: why is it dangerous to eval variables?
    – user13742
    Commented Feb 15, 2012 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
    Commented Feb 15, 2012 at 18:18
  • adding eval in front of $1 worked, since I already had shopt -s expand_aliases. Thanks!
    – Jayson
    Commented Feb 15, 2012 at 22:13
2

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; }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .