从bash shell脚本中的glob目录内的命令行执行命令

Gar*_*son 4 directory bash for-loop glob

在bash shell脚本中,do-for.sh我想使用bash在glob中命名的所有目录中执行命令.这已经得到了很多次的回答,但我想在命令行上提供命令.换句话说假设我有目录:

  • foo
  • bar

我想进入

do-for * pwd
Run Code Online (Sandbox Code Playgroud)

并打印内部foobar工作目录然后打印.

从阅读网上的无数答案,我想我可以这样做:

for dir in $1; do
  pushd ${dir}
  $2 $3 $4 $5 $6 $7 $8 $9
  popd
done
Run Code Online (Sandbox Code Playgroud)

显然,虽然glob *扩展到其他命令行参数变量!所以第一次通过循环,因为$2 $3 $4 $5 $6 $7 $8 $9我的预期,foo pwd但它似乎我得到foo bar!

如何保持命令行上的glob不被扩展为其他参数?或者有更好的方法来解决这个问题吗?

为了更清楚,这是我想要使用批处理文件的方式.(顺便说一句,这适用于Windows批处理文件版本.)

./do-for.sh repo-* git commit -a -m "Added new files."
Run Code Online (Sandbox Code Playgroud)

Fre*_*red 6

我会假设你对那些必须提供某种分隔符的用户开放,就像这样

./do-for.sh repo-* -- git commit -a -m "Added new files."
Run Code Online (Sandbox Code Playgroud)

你的脚本可以做类似的事情(这只是为了解释这个概念,我还没有测试过实际的代码):

CURRENT_DIR="$PWD"

declare -a FILES=()

for ARG in "$@"
do
  [[ "$ARG" != "--" ]] || break
  FILES+=("$ARG")
  shift
done 

if
  [[ "${1-}" = "--" ]]
then
  shift
else
  echo "You must terminate the file list with -- to separate it from the command"
  (return, exit, whatever you prefer to stop the script/function)
fi
Run Code Online (Sandbox Code Playgroud)

此时,您拥有数组中的所有目标文件,"$ @"仅包含要执行的命令.剩下要做的就是:

for FILE in "${FILES[@]-}"
do
  cd "$FILE"
  "$@"
  cd "$CURRENT_DIR"
done
Run Code Online (Sandbox Code Playgroud)

请注意,此解决方案的优势在于,如果您的用户忘记了" - "分隔符,她将收到通知(而不是由于引用导致的失败).