OscarAkaElvis
OscarAkaElvis

Reputation: 5714

Bash. Define an alias from two vars

before asking this, I already checked this, this and this possible related posts and I didn't be able to find the solution. Are quite different alias situations. I hope this is not a duplicate.

I have an array of possible aliases:

declare -A possible_alias_names=(
                ["command1"]="command2"
                #This is an array because there are more
                #But for the example is enough with one in the array
)

What I want is to test if command1 exists and can be launchable. And if is not launchable, to create an alias with the possible_alias_names. I mean, if we can't launch command1, I want to be able to try to launch command2.

I use hash to test if a command exists in the system and works very well. I want to keep (if possible) to still using hash.

For the example, command1 doesn't exist in the system and command2 exists. So the target is to check every key in the array to see if possible to launch that commands (stored in keys). And if not exist, create an alias to launch the corresponding value of the array.

Maybe is more understandable with the array in this way:

declare -A possible_alias_names=(
                ["thisCmdDoentExist"]="ls"
)

The ls command is going to exist, so the point is to be able to create an alias like this syntax alias thisCmdDoentExist='ls'

This is my full NOT WORKING code:

#!/bin/bash

declare -A possible_alias_names=(
                ["y"]="yes"
)

for item in "${!possible_alias_names[@]}"; do
    if ! hash ${item} 2> /dev/null; then
        if hash ${item} 2> /dev/null; then
            echo "always enter here because the command ${item} is not available"
        fi
        alias "${item}='${possible_alias_names[$item]}'"
        #I also tried... alias ${item}='${possible_alias_names[$item]}'
        #I also tried... alias ${item}="${possible_alias_names[$item]}"

        if hash ${item} 2> /dev/null; then
            echo "You win!! alias worked. It means ${item} is available"
        fi
    fi
done

It seems the problem is the expansion because between single quotes it doesn't take the value. I also tried with eval unsuccessfully:

#!/bin/bash

declare -A possible_alias_names=(
                ["y"]="yes"
)

for item in "${!possible_alias_names[@]}"; do
    if ! hash ${item} 2> /dev/null; then
        if hash ${item} 2> /dev/null; then
            echo "always enter here because the command ${item} is not available"
        fi
        alias_cmd1="${item}"
        alias_cmd2="${possible_alias_names[$item]}"
        eval "alias ${alias_cmd1}='${alias_cmd2}'"
        #I also tried... eval "alias ${alias_cmd1}=\'${alias_cmd2}\'"

        if hash ${item} 2> /dev/null; then
            echo "You win!! alias worked. It means ${item} is available"
        fi
    fi
done

I never get the second echo to see "You win!!" message. The alias is not working! how can I do?

Upvotes: 0

Views: 533

Answers (1)

that other guy
that other guy

Reputation: 123470

Here's an easier way of reproducing your problem:

#!/bin/bash
alias foo=echo
foo "Hello World"
hash foo

Here's what happens when you run it:

$ bash myscript
myscript: line 3: foo: command not found
myscript: line 4: hash: foo: not found

$ foo "Hello World"
bash: foo: command not found

The issues here are:

  1. Aliases are not enabled in scripts by default.
  2. hash does not recognize aliases.

And depending on what you expect from this script:

  1. Even if you enable aliases, they won't be available after the script is finished.

To fix all three, you should source the script from an interactive shell, and use type instead of hash:

$ cat myscript
alias foo=echo
foo "Hello World"
type foo

And then source it:

$ source myscript
Hello World
foo is aliased to `echo'

$ foo "Hello World"
Hello World

Some of your attempts at setting aliases would now work successfully, but the best way would be:

key="foo"
value="echo"
alias "$key=$value"

Upvotes: 1

Related Questions