Bash обычно не заботится о значениях аргументов, его больше волнует их порядок и то, как они разделены в командной строке, по умолчанию разбирая их на основе пробела между каждым аргументом.
Вы можете увидеть это на примере простой конструкции цикла for
в сценарии оболочки, например, так:
#!/bin/bash
echo ""
echo "ARGS: $@"
echo ""
echo "parsed args:"
for i in "$@"; do
echo "$i"
done
$ ./parse.bash -f aPHPscript.php -d memory_limit=120M -d apc=1 \
-d max_execution_time=120
ARGS: -f aPHPscript.php -d memory_limit=120M -d apc=1 -d max_execution_time=120
parsed args:
-f
aPHPscript.php
-d
memory_limit=120M
-d
apc=1
-d
max_execution_time=120
В приведенном выше примере каждая итерация цикла "отслаивает" следующий аргумент, переданный в сценарий parse.bash
. Поэтому вместо использования getopts
вы всегда можете сделать что-то вроде этого.
Я обычно не использую getopts
и делаю все так, как вы спрашиваете, например, с помощью цикла while
, используя оператор case
для разбора аргументов по мере необходимости.
$ more parse2.bash
#!/bin/bash
while [[ $# > 1 ]]
do
key="$1"
shift
# -f aPHPscript.php -d memory_limit=120M -d apc=1
#+ -d max_execution_time=120
case $key in
-f)
f_ARG="$1"
shift
;;
-d)
d_ARGS=( "${d_ARGS[@]}" "$1" )
shift
;;
*)
# unknown option
;;
esac
done
echo "$f_ARG"
echo "${d_ARGS[@]}"
Когда мы запускаем его с вашими аргументами, мы видим, что он смог разобрать ваши -d
аргументы в массив, $d_ARGS
.
$ ./parse2.bash -f aPHPscript.php -d memory_limit=120M -d apc=1 \
-d max_execution_time=120
aPHPscript.php
memory_limit=120M apc=1 max_execution_time=120
К сожалению, эта информация отсутствует на справочных страницах, и даже зная, как их читать, (см. ниже )вы столкнетесь с трудностями при попытке найти эту информацию.
Тем не менее, красота открытого исходного кода зависит от возможности читать исходный код. Если вы посмотрите наudev-builtin.c
исходный файл в репозитории systemd
/ udev
и имеете базовые знания языка C , вы найдете следующий фрагмент кода :Структура, которая отображает все существующие встроенные типы.
static const struct udev_builtin *builtins[_UDEV_BUILTIN_MAX] = {
#if HAVE_BLKID
[UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
#endif
[UDEV_BUILTIN_BTRFS] = &udev_builtin_btrfs,
[UDEV_BUILTIN_HWDB] = &udev_builtin_hwdb,
[UDEV_BUILTIN_INPUT_ID] = &udev_builtin_input_id,
[UDEV_BUILTIN_KEYBOARD] = &udev_builtin_keyboard,
#if HAVE_KMOD
[UDEV_BUILTIN_KMOD] = &udev_builtin_kmod,
#endif
[UDEV_BUILTIN_NET_ID] = &udev_builtin_net_id,
[UDEV_BUILTIN_NET_LINK] = &udev_builtin_net_setup_link,
[UDEV_BUILTIN_PATH_ID] = &udev_builtin_path_id,
[UDEV_BUILTIN_USB_ID] = &udev_builtin_usb_id,
#if HAVE_ACL
[UDEV_BUILTIN_UACCESS] = &udev_builtin_uaccess,
#endif
};
Этот struct
содержит все встроенные -типы и сопоставляет исходные файлы в зависимости от типа. Пример:
udev-builtin-kmod.c
-Загрузчик модуля ядра. udev-builtin-keyboard.c
-Обработчик клавиатуры. udev-builtin-usb_id.c
-Обработчик USB, который установит тип USB и инициализирует устройство. Похожие:
Не уверен, если вы не найдете ничего лучше, попробуйте изучить, какие встроенные модули доступны непосредственно в исходниках :найдите файлы, начинающиеся с «udev -встроенный»
Если вы просто запустите udevadm test-builtin
без аргументов, он отобразит список встроенных команд вместе с кратким описанием каждой из них:
udevadm test-builtin --help
calling: test-builtin udevadm test-builtin [OPTIONS] COMMAND DEVPATH Test a built-in command. -h --help Print this message -V --version Print version of the program Commands: blkid Filesystem and partition probing btrfs btrfs volume management hwdb Hardware database input_id Input device properties keyboard Keyboard scan code to key mapping kmod Kernel module loader net_id Network device properties net_setup_link Configure network link path_id Compose persistent device path usb_id USB device properties uaccess Manage device node user ACL
К сожалению, как вы заметили, использование встроенных функций в руководстве объясняется лишь кратко.
Практический пример можно найти в файле 50-udev-default.rules
, доступном в вашей системе (под /lib/udev/rules.d/
), который содержит такие вещи, как:
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}"