30

I set up aliases in /etc/profile.d/alias.sh for each login shell. But if I run script.sh, I can't use that alias. How can I set alias even for subshells or child processes ?

/etc/profile.d/alias.sh

alias rmvr='rm -rv';
alias cprv='cp -rv';
alias mvrv='mv -rv';
lisak
  • 435
  • 1
  • 4
  • 9

5 Answers5

32

If you want them to be inherited to sub-shells, use functions instead. Those can be exported to the environment (export -f), and sub-shells will then have those functions defined.

So, for one of your examples:

rmvr() { rm -rv "$@"; }
export -f rmvr

If you have a bunch of them, then set for export first:

set -a # export the following funcs
rmvr() { rm -rv "$@"; }
cpvr() { cp -rv "$@"; }
mvrv() { mv -rv "$@"; }
set +a # stop exporting
Droj
  • 619
  • 7
  • 5
30

Aliases are not inherited. That's why they are traditionally set in bashrc and not profile. Source your script.sh from your .bashrc or the system-wide one instead.

jw013
  • 1,281
  • 9
  • 17
  • By inhereted, you mean that for instance exported variables are inherited and the rest is not ? – lisak Aug 05 '11 at 16:03
  • 3
    I don't think that .bashrc helps... If you use that alias then in a subshell, it doesn't know it – lisak Aug 05 '11 at 16:06
  • 1
    bashrc is read for all interactive non-login shells which is why this should work since most shells you start up are interactive non-login shells, and aliases do work in subshells with `()` – jw013 Aug 05 '11 at 16:12
  • I didn't know about aliasName() invocation, thank you – lisak Aug 05 '11 at 16:18
  • 1
    Just to be clear, what I meant was in bash, `alias foo='echo foobar'`, enter, `(foo)` outputs `foobar`. – jw013 Aug 05 '11 at 16:21
11

It is because /etc/profile.d/ is used only by interactive login shell. However, /etc/bash.bashrc is used by interactive non-login shell.

As I usually do set some global aliases for system, I have started to create /etc/bashrc.d where I can drop a file with some global aliases:

    HAVE_BASHRC_D=`cat /etc/bash.bashrc | grep -F '/etc/bashrc.d' | wc -l`

    if [ ! -d /etc/bashrc.d ]; then
            mkdir -p /etc/bashrc.d
    fi
    if [ "$HAVE_BASHRC_D" == "0" ]; then
        echo "Setting up bash aliases"
            (cat <<-'EOF'
                                    if [ -d /etc/bashrc.d ]; then
                                      for i in /etc/bashrc.d/*.sh; do
                                        if [ -r $i ]; then
                                          . $i
                                        fi
                                      done
                                      unset i
                                    fi
                            EOF
            ) >> /etc/bash.bashrc

    fi
Simon Sheehan
  • 9,114
  • 12
  • 52
  • 71
atus
  • 111
  • 1
  • 2
0

Similar question, I wanted to run bash "command mode" and have aliases available:

bash -i 'alias' does nothing. But I discovered the -i flag which does run the interactive setups, so this: bash -ci 'alias' does work.

For your question, appears you can kind of circumvent it by "sourcing" the file, ex:

 bash -ci '. script.sh'

Then aliases work. FWIW...

rogerdpack
  • 2,146
  • 7
  • 32
  • 49
-1

You can use case statement like this:

function execute() {
        case $1 in
                ls) $@ --color=auto ;;
              grep) $@ --color=auto ;;
             fgrep) $@ --color=auto ;;
             egrep) $@ --color=auto ;;
                 *) $@ ;;
        esac
}


( execute $@ )

rojen
  • 101