2013-08-24 3 views
0

я наткнулся на следующие скрипты и есть то, что я не могу полностью понятьИсточник другие сценарии в сценарии запуска Linux

#!/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 "[email protected]" 
     start "[email protected]" 
} 

boot() { 
     start "[email protected]" 
} 

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 "[email protected]" || restart "[email protected]" && :' 
$action "[email protected]" 

Надежда некоторые из вас могли бы пролить свет на это. Спасибо!

PS: Еще одна вещь, которую я не совсем понимаю, заключается в том, как функции в сценариях вызывается простым добавлением имени функции в полный путь к сценариям запуска. например, '/etc/init.d/vsftpd test' будет выполнять функцию с именем 'test' в /etc/init.d/vsftpd или /etc/rc.common. Но если функция 'test' определена как в сценарий запуска и /etc/rc.common, функция в первом будет запущена, а в rc.common - нет.

Кроме того, почему не

'[ "$action" = "reload" ] && action='eval reload "[email protected]" || restart "[email protected]" && :' 

просто написана как

'[ "$action" = "reload" ] && action='eval reload "[email protected]" || restart "[email protected]"' 

Спасибо!

+0

Является ли ваш первый образец всем сценарием? – lurker

+0

Да, я просто случайно выбрал простой! все сценарии запуска имеют одну и ту же начальную строку #!/bin/sh /etc/rc.common – benson

+0

«Хеширование» в начале файла может предоставить необязательные аргументы интерпретатору. Поэтому обычно вы можете использовать '#!/Usr/bin/sh [options]'. Но файл сценария не считается «опцией» для оболочки, и я не видел случая, когда сценарий оболочки предлагается в качестве аргумента таким образом. Я сделал быстрый тестовый пример в 'bash' и не наблюдал полезного поведения (т. Е.' Bash' игнорировал необязательный параметр имени файла сценария). Ваш файл 'rc.common' показывает правильный способ включения другого скрипта (предшествует точке (' .')). – lurker

ответ

1

Из execve(2) на достаточно существующей системе Linux:

интерпретатора скриптов

Переводчик Сценарий представляет собой текстовый файл, который имеет разрешение на выполнение включена, и чья первая строка имеет вид:

#! interpreter [optional-arg] 

Интерпретатор должен быть допустимым именем для исполняемого файла, который равен не сам сценарий. Если имя файла аргумент execve() задает сценарий интерпретатор, то интерпретатор будет вызываться с следующими аргументами:

interpreter [optional-arg] filename arg... 

где аг ... есть ряд слов, на который указывает аргумент ARGV execve().

Для портативного использования необязательный-arg должен либо отсутствовать, либо быть указанным как одно слово (то есть оно не должно содержать пробелов); [...]

Я не видел много сценариев в дикой природе, используя #!/bin/sh filename идиомы. Я считаю его использование запутанным.

Возможно, простой тест иллюстрирует. Эти файлы должны присутствовать в/tmp/test, что имеет значение в этом случае, учитывая детали строки интерпретатора в test_interpreter.sh.

Сценарий, названный в "#!" line (rc_interpreter_line) организует запуск команд в первоначально запущенном скрипте, который я выполняю через переменную sourcing_script и команду shift. Код, который вы цитируете в вопросе, делает более сложную версию этой цепочки.Без такого рода цепочек все, что выполняется, - это файл, названный в строке интерпретатора.

Содержание rc_interpreter_line

echo '====' 
echo $0 "[email protected]" 

TESTVAR=set 

sourcing_script=$1 
shift 

. "$sourcing_script" "[email protected]" 

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 "[email protected]" 

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

Второй вызывает оболочку более явно. No execve(2) срабатывает, поэтому этот запуск оболочки просто запускает команды в 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 

... а не полагаться на «интересной» и при этом создавать разные поведения при использовании ./my_script и sh my_script

+0

Спасибо за подробный ответ! но я до сих пор не совсем понимаю, как вызываются функции в сценариях, просто добавив имя функции в полный путь к сценариям запуска. например, '/etc/init.d/vsftpd test' будет выполнять функцию с именем 'test' в /etc/init.d/vsftpd или /etc/rc.common.Thanks снова! – benson

Смежные вопросы