使用 Zsh 循环 grep 结果
第一次登录新虚拟机并设置 WSL 共享文件夹的权限时,我需要循环访问目录。除非设置了 0700 权限,否则 SSH 代理不会添加私钥。
如何使用 grep 获取文件名列表,然后循环遍历它们?
我尝试过:
for file $(grep -lr "-----BEGIN OPENSSH PRIVATE KEY-----")
do
echo "Working on File: $file"
chmod 700 $file
done
结果一团糟。 grep 命令被解析为单个文件名字符串。任何包含空格的映射目录(来自房子的 Win11 一侧)都会使事情变得更加混乱。
I need to loop through a directory the first time I log into a new VM and set permissions on WSL shared folders. The SSH agent will not add private keys unless they have 0700 permissions set.
How do I use grep to get a list of file names and then loop through them?
I tried:
for file $(grep -lr "-----BEGIN OPENSSH PRIVATE KEY-----")
do
echo "Working on File: $file"
chmod 700 $file
done
The results were a mess. The grep command is being resolved into a single string of file names. Any mapped directories that have spaces in them (from the Win11 side of the house) messed things up further.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
建议用一行完成任务:
说明:
-v
:打印每个更改文件的详细报告。grep -lr "-----BEGIN OPENSSH PRIVATE KEY-----" $PWD
:列出当前目录下所有文件中所有匹配的要更改的文件。注意:还尝试将
$PWD
替换为$HOME
。Suggesting to accomplish the task in one line:
Explanation:
-v
: Print verbose report on each changed file.grep -lr "-----BEGIN OPENSSH PRIVATE KEY-----" $PWD
: List all matched files to be changed, from all files under current directory.Note: also try to replace
$PWD
with$HOME
.这是我的解决方案:
最终结果:
后人详细解释:
Zsh 将在子 shell 中执行 () 内的任何内容。所以 grep 的结果在一个无名变量 $() 中。
Zsh 使用 ${} 进行变量/参数扩展。里面的任何内容都会被展开,就像在命令提示符下按“Tab”一样。
我们知道 grep 将返回其中包含空格的文件路径。因此我们不能使用空格来扩展文件列表。我们可以使用标志来实现 grep 和 Zsh 使用空字符作为分隔符而不是空格。
Zsh 标志在大括号打开后立即指定。
grep -lrZ 将在使用 * 通配符找到的所有文件中查找字符串“-----BEGIN OPENSSH PRIVATE KEY-----”。
因此,您最终会使用 grep 查找文件,Zsh 扩展列表,然后循环遍历返回数组中的每个项目。
作为 WSL 中的旁注,您必须打开元数据才能挂载 Windows 文件夹并设置 Linux 权限。这是一个很好的解决方案,可以将 ssh 密钥保存在安全的备份位置并在 Linux 映像上使用它们。
Here is my solution:
The final result:
A detailed explanation for posterity:
Zsh will execute anything inside () in a subshell. so the results of grep are in a nameless variable $().
Zsh does variable/parameter expansion with ${}. Anything inside gets expanded like hitting "Tab" at the command prompt.
We know that grep is going to return file paths with spaces in them. Therefore we can't use whitespace to expand our file list. We can use flags to make it happen with grep and Zsh using null characters as delimiters instead of spaces.
Zsh flags are specified immediately after the curly braces are opened up.
grep -lrZ will look for the string "-----BEGIN OPENSSH PRIVATE KEY-----" in all files found with the * wildcard.
So you end up with grep finding the files, Zsh expands the list and then loops through each of the items in the returned array.
As a side note in WSL, you have to turn on metadata in order to mount a windows folder and set Linux permissions. It is a nice solution to keep your ssh keys in a secure, backed-up location and use them on Linux images.
迭代所有文件,但仅对
grep
成功的文件进行操作。 (您可能没有那么多文件;不必太担心grep
必须运行多少次。)并且因为这是
zsh
,所以您可以嵌入在 glob 中调用grep
:或者甚至省去显式循环
(shell 函数实际上并不是必需的,但它确实有助于提高 glob 限定符的可读性。)
Iterate over all the files, but only operate on the ones that
grep
succeeds on. (You probably don't have that many files; don't worry so much over how many timesgrep
has to run.)And because this is
zsh
, you can embed the call togrep
in the glob:or even dispense with the explicit loop
(The shell function isn't actually necessary, but it does help with the readability of the glob qualifier.)