如何使用传递给使用 xargs 的 shell 脚本的命令行参数?

如何使用传递给使用 xargs 的 shell 脚本的命令行参数?

我有一个脚本,它将迭代一组 git checkout 并在每个目录中运行 git 命令。

我现在希望能够从命令行将参数传递给 shell 脚本,并将该参数合并到正在运行的 git 命令中。

我正在使用以下脚本作为测试(我已删除 git 命令,直到我可以看到正在显示的参数)。

#!/usr/bin/env bash
find . -type d -exec test -e '{}/.git' ';' -print -prune | xargs -P 1 -I {} sh -c 'cd {}; echo `pwd` $1; echo ""'

如果我运行带有参数的命令,我希望看到包含 .git 目录和参数的目录的名称。

我只得到目录名称。

经过大量的尝试后,我最终得到了这个......

#!/usr/bin/env bash
find . -type d -exec test -e '{}/.git' ';' -print -prune | BRANCH="$1" xargs -P 1 -I {} sh -c 'cd {}; echo `pwd` "${BRANCH}"; echo ""'

有没有我错过的机制?有没有“更好”的方式来传递论点?

答案1

在您的 shell 脚本中,您可以使用内联脚本调用另一个 shell。由于您将此脚本放在单引号之间,因此$1按原样传递。您刚刚启动的新 shell 有自己的一组参数,但恰好是空的。所以在解析时$1它会扩展为空。

在您的工作示例中,您将值分配给在新 shell 中可见的新变量。


如果您只是想查找所有 git 存储库,您也可以复制我all-git下面的脚本。用法很简单: all-git <git command>,例如all-git status -bs

#!/bin/bash

for repo in `find $PWD -type d -name .git`
do
    repo=${repo%.git}
    ( 
        cd $repo
        echo "${repo%/}: " | sed -e "s#$HOME#~#"
        git "$@"
    )
done

答案2

find . -type d -exec test -e '{}/.git' ';' -print -prune | \
    xargs -P $(nproc) -I {} sh -c "cd \"{}\"; echo \"\$(pwd) $1\"; echo "

应该可以,但还要注意您可以调用导出的函数。

OPT="$1"
function doGitWork {
    DIR="$1"
    cd "$DIR"
    echo "$(pwd) $OPT"
}
export -f doGitWork
find . -type d -exec test -e '{}/.git' ';' -print -prune | \
    xargs -P $(nproc) -I {} sh -c "doGitWork \"{}\";"

答案3

使用 GNU Parallel 看起来像这样:

find . -type d -exec test -e '{}/.git' ';' -print -prune |
    parallel 'cd {}; echo $(pwd) {}; echo'

如果您想git pull在所有具有目录的目录中执行以下操作.git

allgit() {
  find . -type d -name .git | 
      parallel --tagstring {//} "cd {//}; git $@"
}
allgit pull

相关内容