Поддерживает ли Bash структуру command.subcommand в дополнение к структуре подкоманды command? Если да, как включить это в сценарии bash?

  1. С помощью выреза (закрепки на конце/):

    ORACLE_HOME=$(printf "%s" "$ORACLE_HOME" | cut -d/ -f1-3)/
    
  2. Использование расширения параметра дважды; первый удаляет первые два элемента каталога, затем второй удаляет оставшиеся элементы исходной переменной:

    suffix=${ORACLE_HOME#/*/*/}
    ORACLE_HOME=${ORACLE_HOME%"$suffix"}
    
3
09.05.2020, 20:35
1 ответ

Это стало довольно распространенным способом предоставления инструмента, который может выполнять несколько действий в зависимости от того, какая «подкоманда» используется. Насколько я знаю, это не стандартизировано, и использование точки в качестве разделителя между именем базовой команды и подкомандой при их совместном написании определенно не является универсальным для этих инструментов.

Некоторые инструменты можно вызывать только с подкомандой, например,git(gitсам по себе предоставляет текст справки, если он вызывается сам по себе ), но предоставляет руководства для подкоманд, таких какman command-subcommand(как и в случае с подкомандами git).

Очевидно, вы нашли инструмент, который может называться command-subcommand(, но с точкой)или как command subcommand. В этом случае,вы, вероятно, обнаружите, что и базовая команда, и каждая комбинированная команда являются либо символическими ссылками, либо жесткими ссылками на один и тот же файл.

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

Ниже приведен пример вымышленной команды process, которая может принимать подкоманду в качестве первого аргумента, как в process action, или вызываться с помощью подкоманды, например process-action.

Этот скрипт реализует следующие подкоманды compile, debugи mogrify.

#!/bin/sh

basecmd=process         # base command name
cmd=${0##*/}            # get command name ( basename "$0" )
subcmd=                 # no sub command yet

# Now pick out the sub command from the command name,
# or from the first argument.  Then fail if unsuccessful.

case $cmd in
        "$basecmd"-*)   # has sub command in command name
                subcmd=${cmd#$basecmd-}
esac

if [ -z "$subcmd" ] && [ "$#" -ge 1 ]; then
        # called as "process action"
        # rather than as "process-action"
        subcmd=$1
        shift   # remove sub command from argument list
fi

if [ -z "$subcmd" ]; then
        echo 'No action' >&2
        exit 1
fi

# Act on the sub command.
# Each action would probably be implemented as a function,
# possibly called as
#     somefunction "$@"
#... passing the remaining command line argument to it.

case $subcmd in
        compile)        # do "compile" action
                echo 'compile'
                ;;
        debug)          # do "debug" action
                echo 'debug'
                ;;
        mogrify)        # do "mogrify action"
                echo 'mogrify'
                ;;
        *)
                printf 'Invalid action "%s"\n' "$subcmd" >&2
                exit 1
esac

Я написал это для POSIX sh, так как нет ничего таинственного, что требовало бы bashдля того, чтобы это работало. Программа на языке C будет делать то же самое, что и программа, написанная на любом другом компилируемом или интерпретируемом языке. Это также не требует Linux; Я пишу и тестирую это на OpenBSD, и оно должно работать на любой системе POSIX.

Наряду с этим базовым processсценарием будет набор жестких или символических ссылок, по одной для каждой подкоманды. Здесь я решил создать жесткие ссылки :

.
$ ls -li
total 8
244420 -rwxr-xr-x  4 kk  wheel  538 May  9 21:55 process
244420 -rwxr-xr-x  4 kk  wheel  538 May  9 21:55 process-compile
244420 -rwxr-xr-x  4 kk  wheel  538 May  9 21:55 process-debug
244420 -rwxr-xr-x  4 kk  wheel  538 May  9 21:55 process-mogrify

Каждое из этих имен — просто другое имя для одного и того же сценария.

Тест -работает:

$./process mogrify
mogrify
$./process-mogrify
mogrify
$./process
No action
$./process-compile
compile
$./process compile
compile
$./process compilee
Invalid action "compilee"
2
28.04.2021, 23:15

Теги

Похожие вопросы