我遇到了以下脚本,有些内容我无法完全理解
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2011 OpenWrt.org
START=50
start() {
mkdir -m 0755 -p /var/run/vsftpd
service_start /usr/sbin/vsftpd
}
stop() {
service_stop /usr/sbin/vsftpd
}
这里如何使用'/etc/rc.common'?
这是rc.common的内容
#!/bin/sh
# Copyright (C) 2006-2011 OpenWrt.org
. $IPKG_INSTROOT/lib/functions.sh
. $IPKG_INSTROOT/lib/functions/service.sh
initscript=$1
action=${2:-help}
shift 2
start() {
return 0
}
stop() {
return 0
}
reload() {
return 1
}
restart() {
trap '' TERM
stop "$@"
start "$@"
}
boot() {
start "$@"
}
shutdown() {
stop
}
disable() {
name="$(basename "${initscript}")"
rm -f "$IPKG_INSTROOT"/etc/rc.d/S??$name
rm -f "$IPKG_INSTROOT"/etc/rc.d/K??$name
}
enable() {
name="$(basename "${initscript}")"
disable
[ -n "$START" -o -n "$STOP" ] || {
echo "/etc/init.d/$name does not have a START or STOP value"
return 1
}
[ "$START" ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}"
[ "$STOP" ] && ln -s "../init.d/$name" "$IPKG_INSTROOT/etc/rc.d/K${STOP}${name##K[0-9][0-9]}"
}
enabled() {
name="$(basename "${initscript}")"
[ -x "$IPKG_INSTROOT/etc/rc.d/S${START}${name##S[0-9][0-9]}" ]
}
depends() {
return 0
}
help() {
cat <<EOF
Syntax: $initscript [command]
Available commands:
start Start the service
stop Stop the service
restart Restart the service
reload Reload configuration files (or restart if that fails)
enable Enable service autostart
disable Disable service autostart
$EXTRA_HELP
EOF
}
. "$initscript"
ALL_COMMANDS="start stop reload restart boot shutdown enable disable enabled depends ${EXTRA_COMMANDS}"
list_contains ALL_COMMANDS "$action" || action=help
[ "$action" = "reload" ] && action='eval reload "$@" || restart "$@" && :'
$action "$@"
希望你们中的一些人能够阐明这一点。谢谢!
PS:另一件我不太熟悉的事情是如何通过简单地将函数名称附加到启动脚本的完整路径来调用脚本中的函数。例如,'/ etc / init.d / vsftpd test'将在/etc/init.d/vsftpd或/etc/rc.common中执行名为'test'的函数。但如果同时定义了'test'函数启动脚本和/etc/rc.common,前者中的函数将运行,而rc.common中的函数则不会。
另外,为什么不是
'[ "$action" = "reload" ] && action='eval reload "$@" || restart "$@" && :'
简单地写成
'[ "$action" = "reload" ] && action='eval reload "$@" || restart "$@"'
谢谢!
答案 0 :(得分:1)
来自execve(2)
的相当新的Linux系统:
翻译脚本
解释器脚本是具有执行权限的文本文件 已启用,其第一行的格式为:
#! interpreter [optional-arg]
解释器必须是可执行文件的有效路径名 本身不是一个脚本。如果execve()的filename参数指定了 解释器脚本,然后将调用解释器 以下论点:
interpreter [optional-arg] filename arg...
其中arg ...是argv参数指向的一系列单词
execve()
。对于便携式使用,可选择-arg应该不存在,或者是 指定为单个单词(即,它不应包含空格); [...]
我没有在使用#!/bin/sh filename
成语的野外看到很多脚本。我发现它的使用令人困惑。
也许一个简单的测试将说明。这些文件应该出现在/ tmp / test中,在这种情况下,给定test_interpreter.sh中解释器行的详细信息。
&#34;#!&#34;中命名的脚本line(rc_interpreter_line)安排在最初调用的脚本中运行命令,我通过sourcing_script变量和shift命令执行此操作。您在问题中引用的代码是一个相当复杂的链接版本。没有这种链接,所有运行的都是在解释器行中命名的文件。
rc_interpreter_line的内容
echo '===='
echo $0 "$@"
TESTVAR=set
sourcing_script=$1
shift
. "$sourcing_script" "$@"
echo '===='
test_interpreter.sh的内容
#!/bin/sh /tmp/test/rc_interpreter_line
echo '-----'
echo "My file name is test_interpreter.sh, but \$0 is $0"
echo Command line: $0 "$@"
echo "TESTVAR is '$TESTVAR'"
echo '-----'
exit 0
权限:
sh-4.2$ ls -l
total 8
-rw-r--r-- 1 dev dev 104 Aug 24 13:36 rc_interpreter_line
-rwxr-xr-x 1 dev dev 191 Aug 24 13:36 test_interpreter.sh
示例运行。首先直接运行test_interpreter.sh。
sh-4.2$ ./test_interpreter.sh -opt arg1 arg2
====
/tmp/test/rc_interpreter_line ./test_interpreter.sh -opt arg1 arg2
-----
My file name is test_interpreter.sh, but $0 is /tmp/test/rc_interpreter_line
Command line: /tmp/test/rc_interpreter_line -opt arg1 arg2
TESTVAR is 'set'
-----
第二个更明确地调用shell。没有execve(2)
行为触发,所以shell的这个运行只是运行test_interpreter.sh中的命令,将第一行视为注释。
sh-4.2$ sh test_interpreter.sh -opt arg1 arg2
-----
My file name is test_interpreter.sh, but $0 is test_interpreter.sh
Command line: test_interpreter.sh -opt arg1 arg2
TESTVAR is ''
-----
但我个人的偏好是完全避免使用成语。在脚本中尽早使用命令就更清楚了:
. /etc/rc.common
...而不是依赖&#34;有趣的&#34; &#39;#&#39!;在使用./my_script
和sh my_script