首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在bash中传递命令行参数,检测参数的内容

在bash中传递命令行参数,检测参数的内容
EN

Stack Overflow用户
提问于 2014-09-05 01:09:49
回答 3查看 90关注 0票数 1

我正在写一个bash脚本

  1. 根据所通过的第一个参数表现不同(到目前为止没有问题)
  2. 将其余的参数传递给命令(到目前为止还没有prob )
  3. 如果参数包含字符串,则行为不同。

看上去:

代码语言:javascript
复制
[[ "${1}" = "-h" || "${1}" = "--help" ]] && echo -e "somehelp"
[[ "${1}" = "echo" ]] && echo ${*:2}
[[ "${1}" = "emerge" ]] && emerge -uDN ${*:2}
some-magic-here

现在,如果我知道

代码语言:javascript
复制
myscript emerge -a whatever whatever2 --option 

它会运行

代码语言:javascript
复制
emerge -uDN -a whatever whatever2 --option

但是,万一“任何”都是包含*的字符串,如

代码语言:javascript
复制
myscript emerge -uDN -a whatever/* whatever2 --option

我希望它能运行

代码语言:javascript
复制
emerge -uDN -a $(eix -u --only-names whatever/*) whatever2 --option

而不是。有小费吗?

EN

回答 3

Stack Overflow用户

发布于 2014-09-05 05:38:56

首先,如果要将*传递给脚本,则必须防止命令行上的shell进行扩展。最简单的方法是引用它:

代码语言:javascript
复制
myscript emerge -a 'whatever/*' whatever2 --option

由于您已经在使用[[操作符,注意:是一个bash 解决方案,不能移植到sh。要确定$3是否包含*,可以使用=~运算符:

代码语言:javascript
复制
[[ "${1}" == "emerge" ]] && {
    [[ "$3" =~ "*" ]] && \
        emerge -uDN $2 $(eix -u --only-names $3) ${*:4} || \
        emerge -uDN ${*:2}
}

如果逻辑有点模糊,还可以将复合命令重写为嵌套的if-else语句。试试看,如果你有任何问题,请告诉我。

票数 1
EN

Stack Overflow用户

发布于 2014-09-05 04:28:04

您提到命令行:

代码语言:javascript
复制
myscript emerge -uDN -a whatever/* whatever2 --option

myscript在其参数列表中查看*的唯一方法是,如果当前目录下没有子目录whatever,或者它是一个空目录(严格地说:如果它包含任何文件,则名称都以.开头),在这两种情况下,您都没有设置shopt -s nullglob。如果不满足这些条件,调用myscript的shell将适当地替换* (In),而myscript将看不到*。(当然,如果引用参数- "whatever/*"'whatever/*',那么myscript也会看到*元字符,而不管nullglobwhatever子目录的存在与否。)

目前尚不清楚*是否只需要在遵循-a选项时才需要替换,或者是否需要在任何参数中替换它。我将假定所有参数都需要替换;如果应该替换的只是-a之后的参数,则没有太大的不同。

如果没有处理whatever/*的代码,该命令如下所示:

代码语言:javascript
复制
[[ "${1}" = "emerge" ]] && exec emerge -uDN "${@:2}" || exit 1

差异:

  1. exec是可选的,但保证在emerge命令之后不会执行任何东西(除非找不到emerge命令,在这种情况下,|| exit 1确保不执行任何其他命令)。
  2. 使用"$@"保存脚本中显示的参数。没有双引号,$@$*之间就没有区别。在双引号中,"$*"生成一个字符串,但"$@"生成传递给脚本的每个参数。"${@:2}"表示法用于第二个参数到最后一个参数。

要处理任何参数的*,我们需要检测*。如果我们使用数组,这将是最简单的。

数组arglist将包含要传递给emerge命令的参数。我们需要迭代脚本的参数,检查*的外观

代码语言:javascript
复制
arglist=( "-uDN" )
for arg in "${@:2}"
do
    case "$arg" in
    (*\**) arglist+=( $(eix -u --only-names "$arg") );;
    (*)    arglist+=( "$arg" );;
    esac
done
exec emerge "${arglist[@]}"
exit 1

请注意,这假设eix将展开元字符(确切地说,是*),而不是依赖于shell。它还假设,正如问题所假设的,在eix生成的名称中没有空格。如果有,$(…)符号将在空格(或制表符,或换行符,…)处拆分名称。。

最好将此代码作为then子句的主体处理。

代码语言:javascript
复制
if [[ "${1}" = "emerge" ]]
then
    …
fi

这将比试图将所有这些代码挤到一行(这是可以完成的,但这样做没有意义,而且很多不这样做的要点)更清楚。

票数 0
EN

Stack Overflow用户

发布于 2014-09-05 01:15:24

以下是一条线索:

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

x="bbbccc"     # Put different strings in here, and see what happens

case "$x" in
*\**)
    echo "Yes"
    ;;
    *)
    echo "No"
    ;;
esac
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25677266

复制
相关文章

相似问题

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