我的动机是我正在使用多个git存储库,并且我希望在所有这些存储库上运行git status
以查看它是什么。
当我经常在存储库之间切换时,我将它们放在pushd
堆栈中,由dirs -v
显示为:
0 /d/dev/helperscripts
1 /d/dev/mainsite
2 /d/dev/satellitesite
3 /d/dev/apithing
我已尝试使用xargs
循环播放它们,如下所示:
dirs | xargs -n 1 -I % bash -c 'cd -- "%" && git status '
但是,这会出现以下错误:
bash: line 0: cd: /d/dev/helperscripts /d/dev/mainsite /d/dev/satellitesite /d/dev/apithing: No such file or directory
我发现这令人惊讶,因为下面的结果是按预期的目录的换行符列表:
dirs | xargs -n 1 echo
答案 0 :(得分:1)
dirs 命令打印堆栈上以空格分隔的目录列表,但在使用 xargs 和-I
选项时, xargs 期望输入由换行符分隔。使用 dirs 的-p
选项返回每行一个目录的堆栈,这将为 xargs 提供所需的内容。
此外,Bash通常会使用 dirs 列表中的~
替换您的主目录。这可能会导致命令失败,因为替换将目录括在引号中,~
在引用时失去其特殊含义。使用{strong> dirs 的-l
选项强制它始终返回完整的未缩写路径。
dirs -p -l | xargs -n 1 -I % bash -c 'cd -- "%" && git status '
编辑:
我原来的解决方案旨在回答为什么 xargs 在 dirs 的输出上窒息的主要问题。但是,正如Ole Tange在评论中正确指出的那样,它仍然不能正确处理带有空格或其他shell元字符的目录名。这正是xargs -0
旨在解决的问题,但是Bash没有提供使用NULL作为分隔符来显示目录堆栈的便捷方法。
另一种选择是循环遍历$DIRSTACK
数组,该数组包含 dirs 会产生的相同列表:
function dirs_git_status
{
for d in "${DIRSTACK[@]}"
do
git --git-dir="${d}/.git" --work-tree="$d" status
done
}
"${DIRSTACK[@]}"
表示法确保将每个完整的数组元素复制到$d
,并且只要在循环内的双引号内使用$d
,就应保留元字符并且按原样传递给 git ,而不是由Bash评估。
答案 1 :(得分:0)
如果你使用GNU Parallel,它也可以工作:
mkdir ~/tmp
cd ~/tmp
# Make some crazy dirs
mkdir -- -a'" "'"' '"b '<#&|()$@!!'
pushd -- -a*b
pushd ..
pushd '<#&|()$@!!'
pushd ../..
dirs -p | parallel cd -- '{= s/^~/$ENV{HOME}/ =}' '&&' pwd
dirs -p -l | parallel cd -- {} '&&' pwd