如何在shell脚本中对简写运算符进行分组?

发布于 2025-01-20 19:02:28 字数 598 浏览 3 评论 0原文

此 shell 脚本采用一个 -P 可选选项。

#!/bin/sh

usage() {
        echo "Usage: $0 [-P path] URL [URL...]";
        exit 0;
}

P='/default_path/'

getopts "P:" OPT &&  [ "$OPT" == 'P' ] && P=$OPTARG || usage

如果有选项,请执行以下操作。

如果选项是“P”,则将 $OPTARG 路径分配给变量 P。

如果选项不是“P”,则打印用法并退出。

当没有选项时,上面的语句定义失败。当没有给出选项时,getopts "P:" OPT 返回 false,然后调用 usage。根据想法,我应该对表达式的后面部分进行分组,如下所示。但它给了我语法错误。

getopts "P:" OPT &&  { [ "$OPT" == 'P' ] && P=$OPTARG || usage }

如何在shell脚本中对简写运算符进行分组?

This shell script takes one -P optional option.

#!/bin/sh

usage() {
        echo "Usage: $0 [-P path] URL [URL...]";
        exit 0;
}

P='/default_path/'

getopts "P:" OPT &&  [ "$OPT" == 'P' ] && P=$OPTARG || usage

If there are options, do the followings.

If the option is 'P', then assign the $OPTARG path to the variable P.

If the option is not 'P', print the usage and exit.

The statement above fails the definition when there is no option. When no option is given, getopts "P:" OPT returns false, then usage is called. By idea, I should group the later parts of the expression, as below. But it gives me syntax error.

getopts "P:" OPT &&  { [ "$OPT" == 'P' ] && P=$OPTARG || usage }

How to group shorthand operators in shell script?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

椵侞 2025-01-27 19:02:29

简短答案:使用后添加半颜色。

getopts "P:" OPT &&  { [ "$OPT" == 'P' ] && P=$OPTARG || usage; }

旁注:实际上,我选择使用getopt而不是getopts。它更具用途广泛,而且绝对值得学习它。。

旁注2:SE中有数百个线程谈论Shell脚本,其中一些线程具有数千个upvotes。但是知识是如此分散,而有些人可能专注于用法,缺乏真实的解释。请注意, man bash 首先的资源(我不知道我实际上可以man bash,因为我认为bash不是命令)

。 man bash`] [2]:

simple命令

getopts "P:" OPT

命令是也是管道:

管道是一个或多个命令的序列...

第一个&&表格a list

getopts "P:" OPT && # ... another pipeline

列表是一个或多个管道的序列,由一个操作员分隔;

尽管第一个&&表现得像逻辑,但我尝试以这种方式看到

让我们闯入第二部分。这是 test 表达式,即 compound命令

[ "$OPT" == 'P' ]

[[表达]]

使用==和!=运算符时,操作员右侧的字符串被视为模式,并根据下面在模式匹配下所描述的规则进行匹配,就好像启用了Extglob Shell选项一样。 =操作员等于==。

同样,这是通过&&||加入的三个管道,上面解释了:

[ "$OPT" == 'P' ] && P=$OPTARG || usage

如果我们需要对这些管道进行分组,则需要使用以下格式。它
必须用newline或Semicolon终止

{list; }

列表仅在当前的Shell环境中执行。 列表必须用newline或Semicolon终止。这被称为组命令。返回状态是列表的退出状态。请注意,与Metacharacters(and)不同,{and}是保留的单词,必须发生在允许识别保留单词的情况下。由于它们不会导致单词中断,因此必须将它们与列表或其他壳元素分开。

最后加入第一个简单命令&& 复合命令

getopts "P:" OPT &&  { [ "$OPT" == 'P' ] && P=$OPTARG || usage; }

无法想到此标头名称...

使用圆括号在语法上是正确的。但是它无法设置变量p。这是因为分配将在子壳中运行。

getopts "P:" OPT &&  ( [ "$OPT" == 'P' ] && P=$OPTARG || usage )

(列表)

列表在子壳环境中执行(请参见下面的命令执行环境)。 变量分配和影响外壳环境的命令在命令完成后不会保持生效。返回状态是列表的退出状态。

Short answer: Add a semi-colon after usage.

getopts "P:" OPT &&  { [ "$OPT" == 'P' ] && P=$OPTARG || usage; }

Side note: Actually I opted to use getopt instead of getopts. It is much more versatile and definitely worth learning it.

Side note 2: There are hundreds of threads in SE talking about shell scripts, some with thousands of upvotes. But knowledge is so scattered, while some may focus on usage and lack authentic explanations. Be reminded that man bash is a very cool resource to begin with (which I did not know I can actually man bash as I thought bash was not a command).

Explanation, with reference to [`man bash`][2]:

Simple Command:

getopts "P:" OPT

A command is also a Pipeline:

A pipeline is a sequence of one or more commands ...

The first && forms a List:

getopts "P:" OPT && # ... another pipeline

A list is a sequence of one or more pipelines separated by one of the operators ;, &, &&, or ||, and optionally terminated by one of ;, &, or .

Although the first && behaves like a logical AND, I try to not see it in that way.

Let us break to the second part. This is a test expression, which is a Compound Command:

[ "$OPT" == 'P' ]

[[ expression ]]

When the == and != operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below under Pattern Matching, as if the extglob shell option were enabled. The = operator is equivalent to ==.

Again, these are three pipelines joining by && and ||, which explained above:

[ "$OPT" == 'P' ] && P=$OPTARG || usage

If we need to group these pipelines, we need to use the following format. It
must be terminated with a newline or semicolon.

{ list; }

list is simply executed in the current shell environment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. Note that unlike the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized. Since they do not cause a word break, they must be separated from list by whitespace or another shell metacharacter.

Finally joining the first Simple Command && Compound Commands:

getopts "P:" OPT &&  { [ "$OPT" == 'P' ] && P=$OPTARG || usage; }

Cannot think of this header name ...

Using round brackets is syntactically correct. But it cannot set the the variable P. It is because the assignment will be running in a subshell.

getopts "P:" OPT &&  ( [ "$OPT" == 'P' ] && P=$OPTARG || usage )

(list)

list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes. The return status is the exit status of list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文