编辑——事实证明这一行是罪魁祸首
. /lib/lsb/init-functions
如果我注释掉该行,那么命令实际上就可以运行。为什么会这样呢?我可以在其他初始化脚本中毫无问题地获取此文件。
所以我有一个已放入/etc/init.d
并运行的脚本update-rc.d
。我可以使用 运行此命令sudo /etc/init.d/usbstorage start
,并收到一条消息,表明该命令已启动,但所有命令都没有任何效果。我可以通过输入简单的命令来检查这一点,例如
echo "here here maytee" > /home/pi/some_file.txt"
在脚本中,运行后该文件不存在。下面贴出部分脚本供参考。
#! /bin/sh
### BEGIN INIT INFO
# Provides: usbstorage
# Required-Start: $local_fs
# Required-Stop:
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Automounts external storage if found.
### END INIT INFO
PATH=/sbin:/bin
. /lib/lsb/init-functions
do_start () {
umount /dev/sda1 2> /dev/null || echo "sda1 not already mounted"
mkdir /mnt/usbstorage 2> /dev/null || echo "/mnt/usbstorage already exists"
mount /dev/sda1 /mnt/usbstorage
chown -R pi:pi /mnt/usbstorage
echo "Started usbstorage"
}
do_stop () {
umount /dev/sda1 || echo "sda1 not already mounted"
}
case "$1" in
start)
do_start
;;
restart|reload|force-reload)
do_stop || echo 1
do_start
;;
stop|status)
# No-op
;;
*)
echo "Usage: $0 start|stop" >&2
exit 3
;;
esac
为什么命令拒绝运行?一开始就像是有些东西默默地失败了。
- - 编辑
所以我运行了以下命令:
sudo -i
bash -x /etc/init.d/usbstorage start
并得到这个输出
[ ok ] Starting usbstorage (via systemctl): usbstorage.service.
root@johns-box:~# bash -x /etc/init.d/usbstorage start
+ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
+ . /lib/lsb/init-functions
+++ run-parts --lsbsysinit --list /lib/lsb/init-functions.d
++ for hook in '$(run-parts --lsbsysinit --list /lib/lsb/init-functions.d 2>/dev/null)'
++ '[' -r /lib/lsb/init-functions.d/20-left-info-blocks ']'
++ . /lib/lsb/init-functions.d/20-left-info-blocks
++ for hook in '$(run-parts --lsbsysinit --list /lib/lsb/init-functions.d 2>/dev/null)'
++ '[' -r /lib/lsb/init-functions.d/40-systemd ']'
++ . /lib/lsb/init-functions.d/40-systemd
+++ _use_systemctl=0
+++ '[' -d /run/systemd/system ']'
+++ '[' -n '' ']'
+++ '[' 15898 -ne 1 ']'
+++ '[' -z '' ']'
+++ '[' -z '' ']'
+++ case $(readlink -f "$0") in
++++ readlink -f /etc/init.d/usbstorage
+++ _use_systemctl=1
+++ prog=usbstorage
+++ service=usbstorage.service
++++ systemctl -p CanReload show usbstorage.service
+++ '[' CanReload=no = CanReload=no ']'
+++ '[' start = reload ']'
+++ '[' 1 = 1 ']'
+++ set +e
+++ set +u
+++ '[' xstart = xstart -o xstart = xstop -o xstart = xrestart -o xstart = xreload -o xstart = xforce-reload -o xstart = xstatus ']'
+++ systemctl_redirect /etc/init.d/usbstorage start
+++ local s
+++ local rc
+++ local prog=usbstorage
+++ local command=start
+++ case "$command" in
+++ s='Starting usbstorage (via systemctl)'
+++ service=usbstorage.service
++++ systemctl -p LoadState show usbstorage.service
+++ state=LoadState=loaded
+++ '[' LoadState=loaded = LoadState=masked ']'
+++ '[' start = status ']'
+++ log_daemon_msg 'Starting usbstorage (via systemctl)' usbstorage.service
+++ '[' -z 'Starting usbstorage (via systemctl)' ']'
+++ log_daemon_msg_pre 'Starting usbstorage (via systemctl)' usbstorage.service
+++ log_use_fancy_output
+++ TPUT=/usr/bin/tput
+++ EXPR=/usr/bin/expr
+++ '[' -t 1 ']'
+++ '[' xxterm-256color '!=' x ']'
+++ '[' xxterm-256color '!=' xdumb ']'
+++ '[' -x /usr/bin/tput ']'
+++ '[' -x /usr/bin/expr ']'
+++ /usr/bin/tput hpa 60
+++ /usr/bin/tput setaf 1
+++ '[' -z ']'
+++ FANCYTTY=1
+++ case "$FANCYTTY" in
+++ true
+++ echo -n '[....] '
[....] +++ '[' -z usbstorage.service ']'
+++ echo -n 'Starting usbstorage (via systemctl): usbstorage.service'
Starting usbstorage (via systemctl): usbstorage.service+++ log_daemon_msg_post 'Starting usbstorage (via systemctl)' usbstorage.service
+++ :
+++ /bin/systemctl start usbstorage.service
+++ rc=0
+++ '[' start = status ']'
+++ log_end_msg 0
+++ '[' -z 0 ']'
+++ local retval
+++ retval=0
+++ log_end_msg_pre 0
+++ log_use_fancy_output
+++ TPUT=/usr/bin/tput
+++ EXPR=/usr/bin/expr
+++ '[' -t 1 ']'
+++ '[' xxterm-256color '!=' x ']'
+++ '[' xxterm-256color '!=' xdumb ']'
+++ '[' -x /usr/bin/tput ']'
+++ '[' -x /usr/bin/expr ']'
+++ /usr/bin/tput hpa 60
+++ /usr/bin/tput setaf 1
+++ '[' -z 1 ']'
+++ true
+++ case "$FANCYTTY" in
+++ true
++++ /usr/bin/tput setaf 1
+++ RED=''
++++ /usr/bin/tput setaf 2
+++ GREEN=''
++++ /usr/bin/tput setaf 3
+++ YELLOW=''
++++ /usr/bin/tput op
+++ NORMAL=''
+++ /usr/bin/tput civis
+++ /usr/bin/tput sc
+++ /usr/bin/tput hpa 0
+++ '[' 0 -eq 0 ']'
+++ /bin/echo -ne '[ ok '
[ ok +++ /usr/bin/tput rc
+++ /usr/bin/tput cnorm
+++ log_use_fancy_output
+++ TPUT=/usr/bin/tput
+++ EXPR=/usr/bin/expr
+++ '[' -t 1 ']'
+++ '[' xxterm-256color '!=' x ']'
+++ '[' xxterm-256color '!=' xdumb ']'
+++ '[' -x /usr/bin/tput ']'
+++ '[' -x /usr/bin/expr ']'
+++ /usr/bin/tput hpa 60
+++ /usr/bin/tput setaf 1
+++ '[' -z 1 ']'
+++ true
+++ case "$FANCYTTY" in
+++ true
++++ /usr/bin/tput setaf 1
+++ RED=''
++++ /usr/bin/tput setaf 3
+++ YELLOW=''
++++ /usr/bin/tput op
+++ NORMAL=''
+++ '[' 0 -eq 0 ']'
+++ echo .
.
+++ log_end_msg_post 0
+++ :
+++ return 0
+++ return 0
+++ exit 0
答案1
TL;博士。您的启动脚本不执行任何操作,因为它已经“启动”,系统说。你需要停止那么你就可以开始它。
正如您在 shell 跟踪输出中看到的,当您运行
sudo /etc/init.d/usbstorage start
在操作系统上使用系统作为首选经理(这是您的情况),那么该行
. /lib/lsb/init-functions
在你的 SysV 风格的脚本中会导致 shell 代码
/lib/lsb/init-functions.d/40-systemd
运行。它基本上认为您需要与您的文件等效的 systemd,因此打印
Starting usbstorage (via systemctl)
然后运行
/bin/systemctl start usbstorage.service
并从那里退出。脚本的其余部分永远不会在此特定进程中执行。
但是,每次有人调用 时systemctl daemon-reload
,都会解析所有 脚本,并在(启动时)或/etc/init.d/*
中为每个脚本创建一个小的 systemd 单元文件。/run/systemd/generator/
/run/systemd/generator.late/
每个脚本的注释块### BEGIN INIT INFO
都会转换为等效的 systemd 依赖项。脚本的单元文件 usbstorage.service 将包含这些行
RemainAfterExit=yes
ExecStart=/etc/init.d/usbstorage start
ExecStop=/etc/init.d/usbstorage stop
/bin/systemctl start usbstorage.service
因此,在脚本执行结束之前发出的Final将简单地使用 arg 再次运行脚本start
,就像您刚才所做的那样。这次环境保持_SYSTEMCTL_SKIP_REDIRECT=true
,因此包含40-systemd
不会导致更多递归,相反您的脚本将正常执行。
那么为什么当你运行它时它没有做任何事情呢?
一切都在RemainAfterExit=yes
一线之中。这会导致 systemd 记录以下事实:开始已经完成,所以当你发出另一个开始它不会执行任何操作,因为它已经启动并“正在运行”。
您需要发出一个停止首先,然后是你的开始实际上会完全运行你的脚本。您可以检查服务的当前状态,例如:
$ sudo systemctl status usbstorage.service
* usbstorage.service - LSB: Automounts external storage if found.
Loaded: loaded (/etc/init.d/usbstorage)
Active: active (exited) since Thu 2016-07-28 15:37:24 CEST; 26min ago
Process: 7977 ExecStart=/etc/init.d/usbstorage start (code=exited, status=0/SUCCESS)
Jul 28 15:37:23 three usbstorage[7977]: <stdout/stderr of your script>
注意它是怎么说的active (exited)
。您可以在日志中查找消息
sudo journalctl -u usbstorage