庆典:得到传递给脚本文字的参数,并执行它们作为命令 [英] bash: get literal parameters passed to a script and execute them as a command

查看:188
本文介绍了庆典:得到传递给脚本文字的参数,并执行它们作为命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a bash script (called foreach_repo) that should execute the passed parameters as a shell command, e.g.:

 foreach_repo hg status

要执行的命令汞状态。 (它在这个仓库的一个复杂的嵌套结构,我有过这样的结构无法控制,但我需要一批经常运行他们)。

should execute the command hg status. (It does this on a complicated nested structure of repositories, I have no control over this structure, but I need to batch operate on them quite often).

这类型的命令是类似于须藤及其他高阶命令;例如 sudo的汞状态将依次执行汞状态以超级用户权限。

This type of command is similar to sudo and other 'higher-order' commands; for example sudo hg status would in turn execute hg status with superuser rights.

在内部,我的脚本执行以下操作(给出的标准输入资料库路径的饲料,由脚本的另一部分创造的 - 无关的这个问题):

Internally, my script does the following (given a feed of repository paths on stdin, created by another part of the script - irrelevant to this question):

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

其中, $ @ 意味着国米preT传递的参数作为存储库中要执行的命令。

Where $@ is meant to interpret the passed arguments as the command to be executed in the repository.

本办法正常工作对简单的命令,例如:

This approach works fine for simple commands, for example

foreach_repo hg status

将正确返回结构的每个库的状态列表。然而,更复杂的命令(带逃脱,报价...)都搞砸了。例如,当我尝试

will correctly return the status list of every repository in the structure. However, more complicated commands (with escapes, quotes ...) are messed up. For example, when I try

foreach_repo hg commit -m "some message"

我得到

abort: message: no such file or directory

由于引号被扒掉,实际执行的命令是:

Because the quotes were stripped off, the actual command executed was:

hg commit -m some message

试图解决方案

手动去除引号,或整个命令传递,一直没有效果,无论是已使用 $ * 而不是 $ @ 。然而,命令,如须藤可以处理这种情况,那就是:

Attempted solutions

Manually escaping the quotes, or the entire command to be passed, has no effect, neither has using $* instead of $@. However, commands like sudo can handle this type of situation, that is:

sudo hg commit -m "some message"

实际上(正确)执行

would actually (and correctly) execute

hg commit -m "some message"

我如何可以完成相同的行为?

How can I accomplish the same behavior?

推荐答案

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

You are on the right track, and almost got it. You just need to use "$@" instead of $@.

下面是一个总结什么 $ * $ @ 做的,不管有没有行情:

Here's a summary of what $* and $@ do, with and without quotes:


  • $ * $ @ 粘贴位置参数,然后tokenise他们(使用 $ IFS )为单独的字符串。

  • 在位置参数作为一个字符串
  • $ *膏,用 $ IFS 的第一个字符(通常一个空间插入每个之间)。

  • $ @膏中的位置参数,为每个参数字符串。

  • $* and $@ paste in the positional arguments, then tokenise them (using $IFS) into separate strings.
  • "$*" pastes in the positional arguments as one string, with the first character of $IFS (usually a space) inserted between each.
  • "$@" pastes in the positional arguments, as a string for each argument.

例如:

$ set foo bar "foo bar:baz"
$ printf "%s\n" $*
foo
bar
foo
bar:baz
$ printf "%s\n" $@
foo
bar
foo
bar:baz
$ printf "%s\n" "$*"
foo bar foo bar:baz
$ printf "%s\n" "$@"
foo
bar
foo bar:baz

下面是当你设置什么样的变化 $ IFS

Here's what changes when you set $IFS:

$ IFS=:
$ printf "%s\n" $*
foo
bar
foo bar
baz
$ printf "%s\n" $@
foo
bar
foo bar
baz
$ printf "%s\n" "$*"
foo:bar:foo bar:baz
$ printf "%s\n" "$@"
foo
bar
foo bar:baz

这篇关于庆典:得到传递给脚本文字的参数,并执行它们作为命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆