dynawo / dynawo-large-scale-validation

Scripts and utilities used for the Project "Validation of dynamic simulations made using the open source tool Dynawo".
MIT License
0 stars 2 forks source link

Accept the use of aliases for the launchers #14

Closed jl-marin closed 3 years ago

jl-marin commented 3 years ago

Shell aliases do not work when the user passes them as the launcher name (for executing either simulator).

jl-marin commented 3 years ago

We investigated this issue, and it turns out to be rather tricky:

  1. To start off, aliases are not inherited to subshells (and, in contrast to shell variables and functions, they can't be "exported"). Therefore, a bash script can only "see" the aliases you define inside; either explicitly or by making the shell interactive, which makes it source ~/.bashrc and thus see the same aliases the user normally has in the interactive command line.
  2. The second problem is that when trying to invoke the alias via a variable, the shell will not interpret & expand the alias. This cannot be fixed with "shopt -s expand_aliases", it's a security restriction. We can get around it in two ways: (a) Using eval, which is rather unsafe; (b) Using the built-in associative array BASH_ALIASES, which contains all the aliases seen by the shell.

See these two minimal demonstration scripts:

$ cat test_executing_aliases.sh 

#!/bin/bash -i
# Aliases cannot be "exported", as it's done for env vars or even functions.
# Only by making it an interactive shell (-i) can we see the aliases (which are read from ~/.bashrc)
echo "Aliases seen from this script:"
alias -p  # note: also visible through the assoc array BASH_ALIASES
echo

# Try passing an alias you've defined in ~/.bashrc
echo "Trying to execute $1 (direct invocation)"
$1  # this doesn't work

echo "Trying to execute $1 (using eval)"
eval $1  # this does

echo "Trying to execute $1 (using BASH_ALIASES)"
${BASH_ALIASES[$1]}  # this does work too

And:

$ cat test_shopt_expand_aliases.sh 

#!/bin/bash
alias xyz='echo Hello World'
xyz  # this doesn't expand b/c it's a non-interactive shell
shopt -s expand_aliases
xyz  # now it does
VAR="xyz"
$VAR  # but it still doesn't help here, you still need eval

Conclusion: we'll fix this by making the shell interactive (-i) and invoking via BASH_ALIASES. The user should be aware that the script will only see the aliases that normally get loaded in an interactive bash session. If you define a new alias on-the-fly, it won't be seen in the script.

jl-marin commented 3 years ago

Actually, using (-i) has a bad side-effect: GNU parallel doesn't seem to like it (it stalls when tryning to run these jobs). Probably because it interprets that the environment is interactive?

Anyhow, this is solved by sourcing ~/.bashrc ourselves explicitly. No need to make the shell interactive. After all, what we really need is to make the user aliases visible to the script.

Commits 5bbc28f3fbb4314023daf60df3bb0824a4121888, aad31be82bee46cd0c4559ae02a20d30db3ca861.