首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >除了命令子命令结构之外,Bash还支持command.subcommand结构吗?如果是,如何将其合并到bash脚本中?

除了命令子命令结构之外,Bash还支持command.subcommand结构吗?如果是,如何将其合并到bash脚本中?
EN

Unix & Linux用户
提问于 2020-05-09 17:35:22
回答 2查看 2.7K关注 0票数 3

在我的本地计算机上安装microk8s (Microk8s)之后,我遇到的一个命令是microk8s.enable dns,它也可以作为microk8s enable dns运行。这似乎不是一件普遍的事情。git status是一个有效的命令,但git.status不是。Linux系统如何支持这种类型的命令结构?我如何将这种行为合并到我的Bash脚本中?

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2020-05-09 19:35:36

有时,您会看到程序(和脚本)检查用于调用程序的文件的名称,以及从中获取的条件行为。

例如,请考虑以下文件和符号链接:

代码语言:javascript
复制
$ ls -l
-rwxr-xr-x  ... foo
lrwxr-xr-x  ... foo.bar -> foo

以及脚本foo的内容:

代码语言:javascript
复制
#!/bin/bash

readonly command="$(basename "${0}")"
subcommand="$(echo "${command}" | cut -s -d. -f2)"

if [[ "${subcommand}" == "" ]]; then
    subcommand="${1}"
fi

if [[ "${subcommand}" == "" ]]; then
    echo "Error: subcommand not specified" 1>&2
    exit 1
fi

echo "Running ${subcommand}"

脚本解析命令名,寻找一个子命令(基于问题中的点符号)。这样,我就可以运行./foo.bar并获得与运行./foo bar相同的行为:

代码语言:javascript
复制
$ ./foo.bar
Running bar

$ ./foo bar
Running bar

明确地说,我不知道microk8s.enable正在做什么。您可以做一个ls -li $(which microk8s.enable) $(which microk8s)并比较这些文件。其中一个是链接到另一个吗?如果没有,它们是否有相同的inode编号?

票数 6
EN

Unix & Linux用户

发布于 2020-05-09 20:08:49

这已经成为提供一个工具的一种相当普遍的方式,它可以根据所使用的“子命令”来执行多个操作。据我所知,这是不标准化的,并且在将它们写在一起时,使用点作为基本命令名和子命令之间的分隔符,对这些工具来说肯定不是通用的。

有些工具只能使用子命令调用,比如git (git本身提供帮助文本,如果只调用它),但是为man command-subcommand这样的子命令提供手册(与git子命令的情况一样)。

很明显,您已经找到了一个可以称为command-subcommand (但带有点)或command subcommand的工具。在这种情况下,您可能会发现基命令和每个组合命令都是指向一个和同一个文件的符号链接或硬链接。

程序(无论是脚本还是已编译的二进制文件)可以很容易地检查它被调用的名称和参数,并相应地调整其操作。

下面是一个虚构的process命令的示例,它可以将子命令作为第一个参数(如在process action中),也可以使用像process-action这样的子命令调用。

这个脚本实现的子命令是compiledebugmogrify

代码语言:javascript
复制
#!/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脚本之外,还有一组硬链接或符号链接,每个子命令都有一个链接。在这里,我选择创建硬链接:

代码语言:javascript
复制
$ 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

这些名称中的每一个只是同一个脚本的另一个名称。

测试运行:

代码语言:javascript
复制
$ ./process mogrify
mogrify
$ ./process-mogrify
mogrify
$ ./process
No action
$ ./process-compile
compile
$ ./process compile
compile
$ ./process compilee
Invalid action "compilee"
票数 5
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/585579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档