如何在Rust的Command中正确传递含括号的find命令参数?
在Rust的Command中正确传递find的分组参数
我有一段可正常运行的bash命令:
find content/posts \( -iname '*.jpg' \) -print0 | xargs -0 -P8 -n2 mogrify -auto-orient
尝试将其转换为Rust代码:
let mut cmd = Command::new("/usr/bin/find") .args([ post.dest_dir(&dest_dir).as_os_str().to_str().unwrap(), "(-iname '*.jpg')", "-print0", ]) .stdout(Stdio::piped()) .spawn() .unwrap(); let output = Command::new("/usr/bin/xargs") .args(["-0", "-P8", "-n2", "mogrify", "-auto-orient"]) .stdin(cmd.stdout.take().unwrap()) .output() .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
执行后报错:
find: (-iname '*.jpg'): No such file or directory exit code: exit status: 1 mogrify: no decode delegate for this image format `' @ error/constitute.c/ReadImage/741. mogrify: no decode delegate for this image format `MD' @ error/constitute.c/ReadImage/741. mogrify: insufficient image data in file `content/posts/2021-06-26-united-states/DSCF1507.JPG' @ error/jpeg.c/ReadJPEGImage_/1120.
问题原因与解决方案
问题核心是find的参数传递错误:
- bash中的
\( -iname '*.jpg' \),反斜杠是用来规避shell对括号的解析;但Rust的Command直接将参数传递给find进程,不需要转义括号。 - 你把整个分组条件作为单个参数传递,会被find当成文件名查找,自然报错。正确做法是将每个部分拆分为独立参数:
(、-iname、*.jpg、)。 - bash中的单引号是防止shell扩展通配符,Rust传递参数不经过shell解析,无需添加单引号。
修正后的Rust代码:
let mut cmd = Command::new("/usr/bin/find") .args([ post.dest_dir(&dest_dir).as_os_str().to_str().unwrap(), "(", "-iname", "*.jpg", ")", "-print0", ]) .stdout(Stdio::piped()) .spawn() .unwrap(); let output = Command::new("/usr/bin/xargs") .args(["-0", "-P8", "-n2", "mogrify", "-auto-orient"]) .stdin(cmd.stdout.take().unwrap()) .output() .unwrap_or_else(|e| panic!("failed to execute process: {}", e));
进阶优化
如果路径可能包含非UTF-8字符,建议使用OsStr传递参数,避免to_str().unwrap()的panic:
use std::ffi::OsStr; let mut cmd = Command::new("/usr/bin/find") .args_os([ post.dest_dir(&dest_dir).as_os_str(), OsStr::new("("), OsStr::new("-iname"), OsStr::new("*.jpg"), OsStr::new(")"), OsStr::new("-print0"), ]) .stdout(Stdio::piped()) .spawn() .unwrap();
内容的提问来源于stack exchange,提问作者tanman
相关产品推荐
相关产品推荐

