使用xargs将命令传递到子shell在别名内部不起作用

时间:2013-02-21 18:11:19

标签: bash alias xargs subshell

我正在尝试构建一个快速脚本来查找目录下的所有git repos并按顺序“git pull”每个。

这是我到目前为止所发现的:

find ~/ -name ".git" -type d | sed 's,/*[^/]\+/*$,,' | xargs -L1 bash -c 'cd "$1" && git pull' _

如果粘贴到终端中,这将完全按照预期工作。但是,如果我将其设置为.bashrc文件中的别名:

alias gpa="find ~/ -name ".git" -type d | sed 's,/*[^/]\+/*$,,' | xargs -L1 bash -c 'cd "$1" && git pull' _"

该命令不起作用。我修改它以试图打印xargs发起的子shell接收的内容:

alias printgpa="find ~/ -name ".git" -type d | sed 's,/*[^/]\+/*$,,' | xargs -L1 bash -c 'echo "$1"' _"

运行时,每个子shell都会打印一个换行符,但没有别的。

任何人都可以回答为什么会这样吗?我的直觉是说我的别名中的语法有问题,但我不确切知道发生了什么。

2 个答案:

答案 0 :(得分:2)

问题是,在定义别名时,$1会被替换,而不是在运行时。为了防止这种情况,您需要引用$,使用反斜杠或使用一些单引号。例如:

alias printgpa='find ~/ -name .git -type d | sed '\''s,/*[^/]\+/*$,,'\'' | xargs -L1 bash -c '\''echo "$1"'\'' _'

答案 1 :(得分:2)

使用GNU Parallel时,可能更容易阅读:

alias gpa="find ~/ -name .git -type d | parallel 'cd {//} && git pull'"

另外,你可以获得额外的好处,即获得更多的gits并行。

安装GNU Parallel需要花费10秒钟的时间:

wget pi.dk/3 -qO - | sh -x

观看介绍视频以了解详情:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1