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"

# 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 \

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?

  • 1
    Remember you can use "which command" to know what exactly is run when you issue "command". – badp Dec 13 '10 at 6:55
  • 2
    which didn't help, because suspend is a builtin. – Chris Conway Dec 13 '10 at 13:13
  • This question seems more appropriate for the Unix & Linux SE site. There is nothing Ubuntu specific about this question. – Dan Moulding Feb 18 '11 at 14:02
  • 1
    Except that I'm a member of this community and I'm not a member of that community and I didn't support the creation of two sites precisely because I didn't want to waste time addressing comments like this. – Chris Conway Feb 19 '11 at 1:27

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.

  -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.

| improve this answer | |
  • I suspected something like this might be the case, but which suspend and man suspend both returned nothing. The former isn't surprising, because which doesn't handle builtins, but the latter is irritating. – Chris Conway Dec 13 '10 at 13:12
  • help suspend is the ticket. – Chipaca Dec 13 '10 at 13:47
  • which is a useless command. Use the builtin type instead. Try, type suspend, type -a suspend and type -P suspend. help type to learn more. But really, just avoid naming your scripts with the name of a shell builtin. – geirha Jan 22 '11 at 17:44

If you want your command to supercede a builtin, you first have to disable the builtion:

enable -n suspend

You can then run your command like a normal command. Then, you re-enable the builtin

enable suspend

I'm surprised the builtin is invoked when you call your command with the full path.

| improve this answer | |

To answer your question about the sh extension; it is actually the opposite, you should not be using it.

Don't use extensions for your scripts. Scripts define new commands that you can run, and commands are generally not given extensions. Also: bash script are not sh script (so don't use .sh) and the extension will only cause dependencies headaches if the script gets rewritten in another language.

From #bash on Freenode.net

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.