Ubuntu – Why does the shell script hang without the .sh extension

bashscripts

I created a shell script /usr/local/bin/suspend with the following content:

#! /bin/sh

# Take an optional delay parameter
if [ "$#" -gt "0" ]; then
  sleep "$1"
fi

# Put the system to sleep
dbus-send --system --print-reply --dest="org.freedesktop.Hal" \
    /org/freedesktop/Hal/devices/computer \
    org.freedesktop.Hal.Device.SystemPowerManagement.Suspend \
    int32:0

If I chmod +x and run the script by invoking it directly (e.g., just typing suspend or /usr/local/bin/suspend on the command line), nothing happens and the shell hangsā€”it doesn't even respond to Ctrl-C; I have to switch to a new shell and kill the bash process (which has no apparent children).

The script works fine if I invoke it in any of the following ways:

  • Using sh /usr/local/bin/suspend.
  • Using . /usr/local/bin/suspend.
  • Renaming it to suspend.sh and invoking /usr/local/bin/suspend.sh (or just suspend.sh, since it's in the PATH).

The last option is fine, but still I wonder: what exactly is wrong with not using the .sh extension?

Best Answer

suspend is a bash builtin,

suspend: suspend [-f]
Suspend shell execution.

Suspend the execution of this shell until it receives a SIGCONT signal.
Unless forced, login shells cannot be suspended.

Options:
  -f    force the suspend, even if the shell is a login shell

Exit Status:
Returns success unless job control is not enabled or an error occurs.

and as builtins take precedence, just typing suspend would behave exactly as you describe: the shell blocks until you kill it (if you kill -CONT it, it resumes).

That you're seeing this same behavior by invoking it with the path is either an experimental error, or a bug in the shell. I'd suspect the former before the latter.

Related Question