bash - 具有多个命令的 xargs 仅适用于某些文件
问题描述
我正在尝试(从我的 Macbook 开始)获取与下一行中的规范匹配的所有图像文件的列表,以及它们的大小和 sha512。我这样做是为了审核我分布在多个系统上的数以万计的此类文件。
sudo find /Users \( -iname '*.JPG' -or -iname '*.NEF' -or -iname '*.PNG'
-or -iname '*.RAF' -or -iname '*.PW2' -or -iname '*.DNG' \) -type f -and
-size +10000k -print0 | xargs -0 -I @@
/bin/bash -c '{ stat -n -f"MACBOOK %z " "@@" && shasum -p -a 512 "@@"; }'
运行时,这会正确生成我想要的某些文件的输出,例如我得到的;
MACBOOK 32465640 <SHA512-REDACTED> ?/Users/<REDACTED>/Pictures/Pendleton Roundup/2018/2018-09-13/_DSC3955.NEF
但是对于某些文件,@@ 替换似乎无法正常工作,而是我得到了;
MACBOOK 28130793 shasum: @@:
如果我在 bash 行中添加一个 -v 标志以打印出我希望在出错时执行的命令,我会看到这个;
{ stat -n -f"MACBOOK %z " "/Users/<REDACTED>/Pictures/Photos Library D750.photoslibrary/Masters/2018/07/29/20180729-223141/DSC_3274.NEF"; shasum -p -a 512 "@@"; }
如果我用文件名替换@@ 手动运行该行,它会按预期工作,所以 xargs 的 -I @@ 参数似乎并不总是有效,我不知道原因可能是什么我。
谁能帮我解决这个问题?我尝试将@@ 放在引号中,尝试使用不同的模式并且总是相同的问题。
解决方案
考虑:
find_args=( -false )
for type in jpg nef png raf pw2 dng; do
find_args+=( -o -name "*.$type" )
done
sudo find /Users '(' "${find_args[@]}" ')' \
-type f \
-size +10000k \
-exec sh -c '
for arg; do
stat -n -f"MACBOOK %z " "$arg"
shasum -p -a 512 "$arg"
done' _ {} +
使用-exec ... {} +
让我们只调用每批文件find
的一个副本(与本地平台上的命令行一样多)。sh
更重要的是,不在参数{}
内部使用sh -c
可以避免命令注入漏洞,该漏洞与原始代码一起允许恶意文件名运行任意命令(当您在 下运行时尤其重要sudo
,因此这些命令将以 root 身份执行!)。
推荐阅读
- java - Spring MVC 与 Spring Boot 与 Spring
- html - 隐藏内容显示并向下滚动时,Chrome 页面会跳转/闪烁
- angular - 禁用 ngx-bootstrap 弹出窗口?
- swift - 如何获取通知权限状态(Swift)?
- c++ - 使用 istream 和 ostream 对象作为类 c++ 的数据成员
- palantir-foundry - 如何在 Contour 中按两列对表格进行排序?
- arm - Cortex M 处理器如何获取指令
- python - 用于条件返回的python docstring
- r - R使用case_when按组跟踪列中的更改
- c++ - 使用 static_cast 从 int 转换为 float 时输出不正确
C++