Почему мой сценарий оболочки висит без расширения .sh?

Я создал сценарий оболочки /usr/local/bin/suspend со следующим содержимым:

 #! /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 

Если я chmod +x и запустил скрипт, вызвав его напрямую (например, просто набрав suspend или /usr/local/bin/suspend в командной строке), ничего не происходит и оболочка зависает – она ​​даже не реагирует на Ctrl- C; Мне нужно переключиться на новую оболочку и убить процесс bash (у которого нет видимых детей).

Скрипт отлично работает, если я вызываю его одним из следующих способов:

  • Использование sh /usr/local/bin/suspend .
  • Использование . /usr/local/bin/suspend . /usr/local/bin/suspend .
  • Переименуйте его в suspend.sh и suspend.sh /usr/local/bin/suspend.sh (или просто suspend.sh , так как он находится в PATH ).

Последний вариант в порядке, но все же я задаюсь вопросом: что именно не так, если вы не используете расширение .sh ?

suspend – это 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. 

и поскольку встроенные имеют приоритет, просто набрав suspend будет вести себя так, как вы описываете: оболочка блокирует, пока вы ее не убьете (если вы kill -CONT , она возобновится).

То, что вы видите такое же поведение, вызывая его с помощью пути, является либо экспериментальной ошибкой, либо ошибкой в ​​оболочке. Я бы заподозрил бывшего перед последним.

Если вы хотите, чтобы ваша команда заработала встроенную версию, вам сначала нужно отключить встроенное приложение:

 enable -n suspend 

Затем вы можете запустить свою команду как обычную команду. Затем вы снова включаете встроенный

 enable suspend 

Я удивлен, что встроенный вызов вызывается, когда вы вызываете свою команду с полным путем.

Чтобы ответить на ваш вопрос о расширении sh; на самом деле это наоборот, вы не должны его использовать.

Не используйте расширения для своих скриптов. Сценарии определяют новые команды, которые вы можете запускать, а командам обычно не предоставляются расширения. Кроме того: сценарий bash не является sh-скриптом (поэтому не используйте .sh), и расширение будет вызывать зависания только в том случае, если скрипт будет перезаписан на другом языке.

Из #bash на Freenode.net