5

I am using Xilinx ISE, a program that requires to source a vendor script to setup the path for all its tools. Since this script breaks some functionalities of my shell I do not want to source it on the start of the shell but only when I need it.

To do so I had setup an alias for source /long/path/to/script. For convenience I would like it if the tools provided by the program would just always work without the setup script. The Idea is to have aliases like the following for each of the n programs (for the sake of example lets assume they are named p1,...,pn)

alias p1='source /long/path/;unalias p1;...;unalias pn;p1'

Since there are many programs I want to ease the updating of the unalias chain. The Idea is to have alias iseRemoveSetup='unalias p1;...;pn'. To make the building of the aliases for the programs and iseRemoveSetup easier I defined a few functions. However if I call iseAddToRemoveCall from the alias command (here for analyzer) it does not have any effect. If I call it directly on the shell however it works fine.

Below is the relevant part of my .bashrc:

alias iseRemoveSetup=''
function iseAddToRemove() {
  alias iseRemoveSetup=`(alias iseRemoveSetup | cut -f2 -d "'")`"unalias $1;"
}
function iseAddToRemoveCall() {
  iseAddToRemove $1
  echo "iseRemoveSetup;$1"
}

alias setupise='source /home/ted/Xilinx/tools/14.7/ISE_DS/settings64.sh'
alias analyzer='setupise;'`iseAddToRemoveCall "analyzer"`

I am aware that it would be an Idea to have a function like:

function iseAlias() {
  alias $1='setupise;'`iseAddToRemoveCall $1`
}

However I want to have the issue I described above fixed first. The issue becomes visible when I run type iseRemoveSetup, it outputs:

iseRemoveSetup is aliased to `'
  • What functionalities of your shell does it break? – Hauke Laging Dec 9 '14 at 13:20
  • What is the ...;unalias pn; in the alias definition good for? Scripts (and binaries) don't use the aliases of the calling shell anyway. – Hauke Laging Dec 9 '14 at 13:26
  • What is the output of alias iseRemoveSetup | cut -f2 -d "'" supposed to be? – Hauke Laging Dec 9 '14 at 13:55
  • @HaukeLaging: I only need to run source /home/ted/... once after that my path is fixed to include the tools. Therefore just running analyzer is enough, no need to source again. The script also adds older libraries to the linker path and some programs cant deal with these older libraries. – ted Dec 9 '14 at 14:14
  • Is that a typo? "However if I call iseAddRemoveCall from the alias command. iseAddRemoveCall` doesn't appear anywhere else. Is that supposed to be iseAddToRemoveCall? – Hauke Laging Dec 9 '14 at 14:22
4

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.

  • I do need the unalias, since it basically turns source /setupscript/;tool into tool. otherwise a second start of the tool would source the setup script again. – ted Dec 9 '14 at 14:18
  • I think I sort of get the problem with iseRemoveSetup beeing empty at the time analyzer is defined. However I do not know why iseRemoveSetup also shows as empty on the bash after freshly starting it (it should update?). While I might invesitgate arrays (I am new to bash scripting), I wonder if I can then call a function from the alias to do the cleanup of alias when the alias is invoked. The funciton would be called at the time I execute the alias if I put it as litteral text, right? – ted Dec 9 '14 at 14:20
  • So how do I work arround the subshell issue? After all I want the addition to the list to be executed. I think adding the iseAlias will help me to get arround the subshell but in general how do I do something like VAR=resultOfFunction X where I execute the resultOfFunction in the same bash but only at definition time? – ted Dec 9 '14 at 16:16
  • @ted I have added a suggestion to the answer. – Hauke Laging Dec 9 '14 at 19:53
  • 1
    @ted You are free to produce more complicated output... But I guess alias analyzer='RunSetupiseOnce;analyzer' is the best solution. – Hauke Laging Dec 10 '14 at 11:57

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.