2

I know that it works for alias instructions in the file .bashrc. However, a shell script ln_hook:

#!/bin/sh
#filename: ln_hook

## http://stackoverflow.com/questions/3648819/how-to-make-symbolic-link-with-cygwin-in-windows-7
## https://cygwin.com/cygwin-ug-net/using-cygwinenv.html
## https://cygwin.com/cygwin-ug-net/using.html#pathnames-symlinks
# export CYGWIN="winsymlinks" # ln -s: The shortcut style symlinks with file extension '.lnk'
# export CYGWIN="winsymlinks:native" # ln -s: plain text file

ln_hook(){ 
    if [[ "-s" == "$1" ]]; then
        cmd /C mklink /H "$(cygpath -aw "$3")" "`cygpath -aw "$2"`"
    else
        echo -e "\033[32m >> $* \033[0m"
        ln "$*"
    fi
}
alias ln='ln_hook'
type ln

(type ln)


# cannot propagate to another shell script

./test_ln

$(dirname $0)/test_ln

## . ./ln_hook
## type ln

and, another shell script:

#!/bin/sh
#filename: test_ln

type ln

Then run . ./ln_hook, output:

ln_hook
ln 是 `ln_hook' 的别名
ln 是 `ln_hook' 的别名
ln 是 /usr/bin/ln
ln 是 /usr/bin/ln

Is there a workaround to make the alias effective when running other scripts?

samm
  • 620
  • 10
  • 22
  • 1
    Aliases are generally not available in non-interactive contexts. Use functions for that. Use `command ln` to avoid your function being recursive. – Etan Reisner Apr 13 '16 at 12:25
  • Hi~ If so, is there an alternative solution to this problem? – samm Apr 13 '16 at 14:21
  • Yes, man bash: builtin shell-builtin [arguments] Execute the specified shell builtin, passing it arguments, and return its exit status. This is useful when defining a function whose name is the same as a shell builtin, retaining the functionality of the builtin within the function. The cd builtin is com‐ monly redefined this way. The return status is false if shell-builtin is not a shell builtin command. – samm Apr 13 '16 at 14:51
  • `command [-pVv] command [arg ...]` Run command with args suppressing the normal shell function lookup. Only builtin commands or commands found in the PATH are executed. If the -p option is given, the search for command is performed using a default value for PATH that is guaranteed to find all of the standard utilities. If either the -V or -v option is supplied, a description of command is printed. The -v option causes a single word indicating the command or filename used to invoke command to be displayed; the -V option produces a more verbose description. – samm Apr 13 '16 at 14:55
  • I'm **sure** there's a good entry for this to be a duplicate of (in the non-recursive function by using `command` sense) but I can't find it at the moment. – Etan Reisner Apr 13 '16 at 15:53
  • Possible duplicate of [Exporting a function in shell](https://stackoverflow.com/q/1885871/608639) – jww May 01 '19 at 20:34

1 Answers1

3

After going into Bash Manual and google, export -f function_name is what I want.

Thank Etan Reisner for the advice about function being recursive and a demo code as follow:

#!/bin/bash --posix
# Avoid an error about function xx() statement on some os, e.g. on ubuntu, Syntax error: "(" unexpected 
# http://ubuntuforums.org/archive/index.php/t-499045.html 

#########################################################################################################
# << A example about exporting a function >>
# hook ln and propagate it to other scripts to pollute the environment of subsequently executed commands
#########################################################################################################

## https://stackoverflow.com/questions/3648819/how-to-make-symbolic-link-with-cygwin-in-windows-7
## https://cygwin.com/cygwin-ug-net/using-cygwinenv.html
## https://cygwin.com/cygwin-ug-net/using.html#pathnames-symlinks
# export CYGWIN="winsymlinks" # ln -s: The shortcut style symlinks with file extension '.lnk'
# export CYGWIN="winsymlinks:native" # ln -s: plain text file

## ln_hook
function ln(){ 
    if [[ "-s" == "$1" ]]; then
        cmd /C mklink /H "$(cygpath -aw "$3")" "`cygpath -aw "$2"`"
    else
        echo -e "\033[32m >>ln $* \033[0m"
        command ln "$*"
    fi
}

## Cannot propagate alias to other scripts
## alias ln='ln_hook'

## export -f ln=ln_hook ## ln_hook.sh: 第 23 行:export: ln=ln_hook: 不是函数

## http://docstore.mik.ua/orelly/unix3/upt/ch29_13.htm
## https://stackoverflow.com/questions/1885871/exporting-a-function-in-shell
export -f ln

echo&&echo "[^-^] After trying ln_hook"

echo -n "main shell: " && type ln

echo -n "subshell: " && (type ln)


echo&&echo "[^-^] Run an external script"

echo 'type ln' > test_ln.sh
./test_ln.sh  
# $(dirname $0)/test_ln.sh


## . ./ln_hook
echo 'You can try: `type ln`, which will output: ln 是函数...'

Here, Demo or Bash shell editor and execute online

Community
  • 1
  • 1
samm
  • 620
  • 10
  • 22
  • FWIW, using `"$@"` is better than `"$*"` in this sort of context, since that preserves the arguments as passed rather than subjecting them to word splitting a second time. Try doing this with a file containing a space, and you'll see what i mean. :) – dannysauer Oct 07 '20 at 13:35