Can’t use alias in script, even if I define it just above!

I have a very wierd case… If I run a script with /bin/bash, it can’t recognize aliases that I set even inside the script. And the most strange thing is

$ cat -n test.sh
    1 #!/bin/bash
    2 alias somecommand='ls -alF'
    3 alias
    4 somecommand
$ ./test.sh
alias somecommand='ls -alF'
./test.sh: line 4: somecommand: command not found

… as shown above, if I run the command “alias” in the script it turns out that bash has taken somecommand into the aliases, but if I run the somecommand itself it will still not be recognized!

Everything is right if I use the command “sh” to run the script.. so is it a bug of bash? Or is there something I’m missing?

Any help is appreciated!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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 [email protected], including any flags that you use), pretty much as the alias alias ls="ls -F" would do:

ls () {
    command ls -F "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d8fc98">[email protected]</a>"
}

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 -- "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="456105">[email protected]</a>" "$name"
    done
    select file in "<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a682e6">[email protected]</a>"; 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.

Method 2

To use interactive features like alias within a bash script you have to run it in an interactive bash shell. For that change the first line to include a -i . So your new script file becomes

#!/bin/bash -i
alias somecommand='ls -alF'
alias
somecommand

Method 3

Kind of a duplicate of a previous question however the answers there are kind of wordy. The short answer is that, for occult reasons, by default bash doesn’t look at aliases defined inside scripts. You have to explicitly tell it to do so via a shopt -s expand_aliases line at the top of said script. Do that and then your script will find somecommand.

Method 4

Just add shopt -s expand_aliases after first line

#!/bin/bash
shopt -s expand_aliases
alias somecommand='ls -alF'
alias
somecommand

This will output

$ /tmp/alias.sh 
alias somecommand='ls -alF'
total 111044
drwxr-xr-x  4 sobi3ch sobi3ch     4096 Aug 22 14:27 ./
drwxr-xr-x 31 sobi3ch sobi3ch     4096 Aug 23 10:19 ../

Aliases for default are only for interactive shells (from man bash)

expand_aliases

If set, aliases are expanded as described above under ALIASES. This option is enabled by default for interactive shells.

Method 5

Use shopt -sq expand_aliases, for example, this code in UTF-8 encoding:

#!/bin/bash

function запрещать() {
    if [ $1 -eq 3 ]
    then
        echo -n "Запрещено. Код ошибки: "
        echo `expr 2 * 3 * 47`
    else
        echo -n "."
        запрещать `expr $1 + 1`
    fi
}

#function запретить() {
#   запрещать 1
#}

shopt -sq expand_aliases
alias запретить='запрещать 1'

запретить

Method 6

source your_script

instead of execute as a new shell, just source your script and alias will be accepted


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x