加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

bash:获取传递给脚本的文字参数并将其作为命令执行

发布时间:2020-12-16 01:47:31 所属栏目:安全 来源:网络整理
导读:目标和背景 我正在编写一个bash脚本(称为foreach_repo),它应该作为shell命令执行传递的参数,例如: foreach_repo hg status 应该执行命令hg status. (它在一个复杂的嵌套存储库结构上执行此操作,我无法控制此结构,但我需要经常批量操作它们). 这种类型的命令
目标和背景

我正在编写一个bash脚本(称为foreach_repo),它应该作为shell命令执行传递的参数,例如:

foreach_repo hg status

应该执行命令hg status. (它在一个复杂的嵌套存储库结构上执行此操作,我无法控制此结构,但我需要经常批量操作它们).

这种类型的命令类似于sudo和其他“高阶”命令;例如,sudo hg status将依次以超级用户权限执行hg status.

在内部,我的脚本执行以下操作(给定stdin上的存储库路径的提要,由脚本的另一部分创建 – 与此问题无关):

while read repo do
    container="$repo/.."
    cd $base/$container
    $@
done

其中$@用于将传递的参数解释为要在存储库中执行的命令.

执行

例如,这种方法适用于简单的命令

foreach_repo hg status

将正确返回结构中每个存储库的状态列表.但是,更复杂的命令(带有转义,引号……)被搞砸了.例如,当我尝试

foreach_repo hg commit -m "some message"

我明白了

abort: message: no such file or directory

因为引号被剥离,所执行的实际命令是:

hg commit -m some message

试图解决方案

手动转义引号或要传递的整个命令都没有效果,也没有使用$*而不是$@.但是,像sudo这样的命令可以处理这种情况,即:

sudo hg commit -m "some message"

实际上(并且正确地)执行

hg commit -m "some message"

我怎样才能完成同样的行为?

解决方法

你走在正确的轨道上,几乎得到了它.你只需要使用“$@”而不是$@.

这里是$*和$@做什么的摘要,有和没有引号:

> $*和$@粘贴位置参数,然后将它们(使用$IFS)标记为单独的字符串.
>“$*”将位置参数粘贴为一个字符串,每个字符串之间插入$IFS的第一个字符(通常是空格).
>“$@”在位置参数中粘贴,作为每个参数的字符串.

例子:

$set foo bar "foo bar:baz"
$printf "%sn" $*
foo
bar
foo
bar:baz
$printf "%sn" $@
foo
bar
foo
bar:baz
$printf "%sn" "$*"
foo bar foo bar:baz
$printf "%sn" "$@"
foo
bar
foo bar:baz

以下是设置$IFS时的更改:

$IFS=:
$printf "%sn" $*
foo
bar
foo bar
baz
$printf "%sn" $@
foo
bar
foo bar
baz
$printf "%sn" "$*"
foo:bar:foo bar:baz
$printf "%sn" "$@"
foo
bar
foo bar:baz

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读