0

I have a script I'm trying to make at least somewhat platform-independent. Because I can't count on the PATHs or shell aliases of my users (some of whom have been known to create aliases matching "reserved words" meaningful to the shell), I've taken to aliasing all non-builtin shell commands with uppercase equivalents. This works fine when I do it semi-manually, e.g.

AWK=/usr/bin/awk
DATE=/bin/date
GREP=/bin/grep

, but not so well when I try it in a function by iterating through an array of commands:

createAliases() {
    COMMANDS=(awk chmod date echo git mkdir)
    WHICH=/usr/bin/which

    for command in ${COMMANDS[@]}; do
        ${command^^}=$($WHICH ${command})
    done
}

, which produces errors like AWK=/usr/bin/awk: No such file or directory. Is my attempt to use the string^^ up-casing mechanism interfering with the variable assignment? It looks like the shell is actually trying to run the (aliased) commands, which is not what I want.

Any assistance is appreciated!

  • Aliases are not expanded in non-interactive scripts by default. – choroba Jan 29 '21 at 22:33
  • `AWK=/usr/bin/awk` is assigning the string `/usr/bin/awk` to the **variable** `AWK`; if, as your title and description states, you're looking to create an alias then you want `alias AWD=/usr/bin/awk`; 2nd issue ... you mention that you can't rely on the settings in `PATH` but you then use `which` (which searches `PATH`) to find the location of your array of commands sooo ... what happens when the `PATH` is complete garbage and `which awk` comes back and tells you `no awk in : ${PATH}` ? – markp-fuso Jan 29 '21 at 22:36
  • By the way, [`which` may return wrong paths in `bash`](https://unix.stackexchange.com/q/85249/187122). Use `type` or `command -v` instead. – Socowi Jan 29 '21 at 23:32
  • Bash has two distinct, unrelated concepts: variables and aliases. Example alias: `alias ls='ls -l'` followed by `ls`. Example variable: `var='ls'; $var`. It sounds like you are using the term "alias" to describe variables, leading to confusion in the answers and comments. See [this question](https://stackoverflow.com/questions/16553089/dynamic-variable-names-in-bash) for how to assign variables given their name as a string. Note that `which` works by examining the PATH, so if you can't rely on the PATH then you can't rely on `which` either. – that other guy Jan 29 '21 at 23:34

1 Answers1

1

The following seems to work:

shopt -s expand_aliases
createAliases() {
    COMMANDS=(awk chmod date echo git mkdir)
    WHICH=/usr/bin/which

    for command in ${COMMANDS[@]}; do
        alias ${command^^}=$($WHICH ${command})
    done
}

Prefixing the assigment with alias actually registers the desired aliases.

The line shopt -s expand_aliases enables you to then use these alias from anywhere in the script, according to https://www.thegeekdiary.com/how-to-make-alias-command-work-in-bash-script-or-bashrc-file/