The problem is that your alias definition (the one of iseRemoveSetup
) is in a subshell:
alias analyzer='setupise;'`iseAddToRemoveCall "analyzer"`
For iseAddToRemoveCall "analyzer"
a subshell is started and the alias definition affects only this subshell which is gone as soon as this line is done.
This could be solved by changing
alias analyzer='setupise;'`iseAddToRemoveCall "analyzer"`
to
alias analyzer='setupise;$(iseAddToRemoveCall analyzer)'
and replacing echo "iseRemoveSetup;$1"
(in iseAddToRemoveCall
) with echo "unalias $1;$1"
. Thus the unalias
would become part of the alias expansion and would be executed in the correct shell.
alternative
All this seems quite strange to me. Wouldn't it make more sense to start a subshell (type bash
), run the setup, run the commands, and leave the subshell (^D
) when finished?
additional remarks
man 1 bash
:
The first word of the replacement text is tested for aliases, but a word that is identical to an alias being expanded is not expanded a second time. This means that one may alias ls to ls -F, for instance, and bash does not try to recursively expand the replacement text.
So you don't need unalias p1
in your alias definition before you call pi
from it.
It may be better to use an (associative) array with the commands you want to unalias and just work with the array.
This is important, too, because you do exactly what you ought not to do:
Bash always reads at least one complete line of input before executing any
of the commands on that line. Aliases are expanded when a command is read, not when it is executed. Therefore, an alias definition appearing on the same
line as another command does not take effect until the next line of input is read. The commands following the alias definition on that line are not
affected by the new alias. This behavior is also an issue when functions are executed. Aliases are expanded when a function definition is read, not when
the function is executed, because a function definition is itself a compound command. As a consequence, aliases defined in a function are not available
until after that function is executed. To be safe, always put alias definitions on a separate line, and do not use alias in compound commands.
Simply don't use aliases in scripts. It makes little sense to use a feature designed for interactive use in scripts. Instead, use functions:
somecommand () {
ls -alF
}
Functions are much more flexible than aliases. The following would overload the usual ls
with a version that always does ls -F
(arguments are passed in $@
, including any flags that you use), pretty much as the alias alias ls="ls -F"
would do:
ls () {
command ls -F "$@"
}
The command
here prevents the shell from going into an infinite recursion, which it would otherwise do since the function is also called ls
.
An alias would never be able to do something like this:
select_edit () (
dir=${1:-.}
if [ ! -d "$dir" ]; then
echo 'Not a directory' >&2
return 1
fi
shopt -s dotglob nullglob
set --
for name in "$dir"/*; do
[ -f "$name" ] && set -- "$@" "$name"
done
select file in "$@"; do
"${EDITOR:-vi}" "$file"
break
done
)
This creates the function select_edit
which takes directory as an argument and asks the user to pick a file in that directory. The picked file will be opened in an editor for editing.
The bash
manual contains the statement
For almost every purpose, aliases are superseded by shell functions.
Best Answer
After some testing, I have concluded the following:
-i
to the shebang).eval $1
. Note thateval
ing 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:
So you could add
shopt -s expand_aliases
instead of-i
.Also,
Since variables are not expanded before the command is read, they will not be expanded further using the alias.