【问题标题】:How do I insert a loop within a command如何在命令中插入循环
【发布时间】:2018-02-20 00:55:12
【问题描述】:

例如:命令(--option * 4次)

我可以在这里使用 for 循环吗?请建议!

换句话说

command --option1 --option2 --option3 --option3 --option3

所以我想循环使用 option3。

【问题讨论】:

  • 应该扩展到command --option --option --option --optioncommand --option command --option command --option command --option 还是什么?
  • BashFAQ #50 是相关的。
  • 你认为的第一个是我正在努力解决的问题。
  • 我现在没有看到 4 次。我看到 1,2,3 或 3,3,3。您想要解决的真正问题是什么?
  • 为什么这个标签是kvm或者centos7?

标签: linux bash shell centos7


【解决方案1】:

请参阅BashFAQ #50,了解为什么解决此问题的幼稚尝试经常失败(或最初似乎可行,但在利用更有趣的数据或更多问题场景时失败)。

谨慎遵循最佳做法的方法可能如下所示:

#!/usr/bin/env bash

number_of_option3s=4
args=( )
for ((i=0; i<number_of_option3s; i++)); do
  args+=( --option3 )
done

your_command --option1 --option2 "${args[@]}"

大概在实际用例中,您会修改args+=( --option="$i" ) 或迭代文件名并执行for file in *.txt; do args+=( --input "$file" ); done 之类的操作;所有这些都会起作用。


如果您没有使用 bash 运行,而是需要使用 /bin/sh,这会变得更丑:

#!/bin/sh

# need to use a function since there's only one array, "$@", but it has a separate
# instance per stack depth.
call_with_repeated_option() {
  number_of_options=$1; shift
  option_to_append=$1; shift
  i=0
  while [ "$i" -lt "$number_of_options" ]; do
    set -- "$@" "$option_to_append"
    i=$((i + 1))
  done
  "$@"
}

# call your_command with 4 "--option3" arguments after --option1 and --option2
call_with_repeated_option 4 --option3 your_command --option1 --option2

【讨论】:

  • @scorp,这意味着你的 shell 不是 bash。确保使用bash scriptname,而不是sh scriptname 运行它,并且将shebang 保持为#!/bin/bash#!/usr/bin/env bash 或类似名称,不是 #!/bin/sh
【解决方案2】:

与:

echo "--option"{0..3}
--option0 --option1 --option2 --option3

 echo "--option"{1,2,3,3,3}
--option1 --option2 --option3 --option3 --option3

这里,命令 echo 使用“--option”调用,粘贴到 (0 到 3) 扩展的结果,或者在第二种情况下,使用逗号分隔的元素列表。

echo "--option"{1..13..4}
--option1 --option5 --option9 --option13

这个相关的结构是用 4 读取 1 到 13。

Duffy 爵士在命令中要求的是一个不同的问题,但很容易以类似的方式解决:

echo command $(echo "--option=\""{a.file,b.file,d.file,e.file}"\"" )
command --option="a.file" --option="b.file" --option="d.file" --option="e.file"

【讨论】:

  • 这种模式具有显着的性能损失(子外壳和管道会产生 fork() 成本),并且不适合实际用例,这些用例通常涉及 --option="filename here"(其中添加的参数随不受控制的数据而变化,因此需要能够在字符串拆分中存活)。
  • @CharlesDuffy:交互式命令的性能损失?真的吗?没有要求您的真实世界用例。也许你的读心能力超过了我。
  • 没有sedcommand {,,,}--option 或者command $(printf -- '--option %0.s' {1..4}) 也可以得到同样的结果。
  • @userunknown,我们在这里是一个教学资源。教授一种容易出现不当行为的做法几乎是站不住脚的。 如果 OP 询问如何编写仅用作交互式命令而不是在脚本上下文中有用的东西,那么这里将是题外话(我们想发送它们转到Unix & Linux)。
  • @userunknown,您的 echo 命令 echo 一个带有正确引用命令的字符串,但如果把echo 拿出来。请参阅BashFAQ #50 了解为什么会这样的完整讨论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 2012-11-29
  • 1970-01-01
相关资源
最近更新 更多