6

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?

4
  • 1
    Remember you can use "which command" to know what exactly is run when you issue "command".
    – badp
    Dec 13, 2010 at 6:55
  • 2
    which didn't help, because suspend is a builtin. Dec 13, 2010 at 13:13
  • This question seems more appropriate for the Unix & Linux SE site. There is nothing Ubuntu specific about this question. Feb 18, 2011 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. Feb 19, 2011 at 1:27

3 Answers 3

10

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.

3
  • 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. Dec 13, 2010 at 13:12
  • help suspend is the ticket.
    – Chipaca
    Dec 13, 2010 at 13:47
  • 1
    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, 2011 at 17:44
2

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.

0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .