我正在Linux上学习bash,我找到了“while循环从文件中读取”的脚本并进行了如下修改,我正在尝试读取包含所有git存储库的列表文件,并且我想迭代所有这些git存储库并运行git status
所有这些:
while read line;
do echo $line;
cd $line;
git status;
done < repo.list
这部分工作正常,我可以在标准输出中看到每个存储库的状态,但是当我尝试将输出写入另一个文件时,它不起作用:
while read line;
do echo $line;
cd $line;
git status;
done < repo.list
> status.txt
我如何整合所有git status
输出并写入文件?谢谢!
答案1
当重定向到新行时,它适用于空命令;要解决此问题,请将其放在线上done
:
while IFS= read -r line;
do echo "$line"
(cd "$line"; git status)
done < repo.list > status.txt
也可以看看了解 IFS和理解“IFS=读取-r行”以及有关影响微妙之处的信息的链接问题read
。
cd
一起使用和的子 shellgit status
意味着更改目录不会影响循环的后续迭代,甚至不会影响运行while
.
答案2
我用谷歌搜索了一下,发现这个 find mydir -name .git -type d
你可以做这样的事情,也许:
find . -name '.git' -type d -print -execdir git status \;
这将查找名为 的目录.git
,然后对于每个目录,打印其路径,然后转到包含的目录并git status
在那里运行。 (find -exec
将在原始目录中运行命令,-execdir
转到匹配的文件/目录所在的位置。)
你会得到像这样的输出
./this-stuff/.git
On branch master
Your branch is up to date with 'origin/master'.
并且需要更多的技巧来对其进行后处理.git
。 (例如,-exec sh -c 'echo "${1%.git}"' sh {} \;
代替-print
。)
一般来说,find
如果您想做某事,可能会起作用全部某些子树中的文件/目录,匹配从文件的元数据中显而易见的某些条件。但是,如果您有一个现有列表,则 shell 循环是处理它的最佳方法。
答案3
您的问题是一个简单的打字错误,正如斯蒂芬已经。
git status
在文件中的行给出的每个目录中运行的任务xargs
也可以使用以下命令完成:
xargs -I {} git -C {} status <repo.list >status.txt
这git -C {} status
需要文件中的每一行repo.list
。将会{}
被从文件中读取的行替换,并且选项-C
将使git
实用程序使用status
子命令的替代目录来代替当前目录。
要在每次调用之前输出存储库路径git status
,请调用sh -c
脚本:
xargs -I {} sh -c 'printf "REPOSITORY: %s\n" "$1"; git -C "$1" status' sh {} <repo.list >status.txt
在脚本内部sh -c
,存储库路径名由 给出"$1"
。