annoying ksh builtin aliases: why service stop not work

I observerd a problem on netsnmpd that the service stop not worked with an error:

Usage: kill [-l] [-n signum] [-s signame] job ...
   Or: kill [ options ] -l [arg ...]

But there is no line with a kill command in the whole script! instead it has a stop function

stop() {
        # Stop daemons.
        echo -n "Shutting down $name: "
        pkill -z `zonename` -x $name
}

which is called in the common used case statementcase "$1" in

  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        pgrep -l -z `zonename` -x $name
        RETVAL=$?
        ;;
  restart|reload)
        stop
        start
        RETVAL=$?
        ;;
  condrestart)
        if [ -f /var/run/daemon/$name ]; then
            stop
            start
            RETVAL=$?
        fi
        ;;
  *)
        echo $"Usage: $0 {start|stop|restart|condrestart|status}"
        exit 1
esac

What is the reason for this error?

asked: 2013-08-22 by: cgrzemba


cgrzemba answers:

The reason are builtin aliases in ksh93. See ksh93 MAN page:

   Aliasing is performed when scripts are read, not while  they
   are executed. For an alias to take effect, the alias defini-
   tion command has to be executed  before  the  command  which
   references the alias is read. The following aliases are com-
   piled into the shell but can be unset or redefined:

   autoload='typeset -fu'
   command='command '
   fc=hist
   float='typeset -lE'
   functions='typeset -f'
   hash='alias -t --'
   history='hist -l'
   integer='typeset -li'
   nameref='typeset -n'
   nohup='nohup '
   r='hist -s'
   redirect='command exec'
   source='command .'
   stop='kill -s STOP'
   suspend='kill -s STOP $$'
   times='{ { time;} 2>&1;}'
   type='whence -v'

Here you can see that the shell defines stop as alias for kill -s STOP. This magic is very annoying and cost me a lot of time.

Finally, insert on top of the script

unalias stop

helps to prevent the problem!