我正在编写一段代码,用于检查
stdin
是否代表一个目录,如果是,则对其执行一些操作
目前,我有可以在 Unix 系统上运行的代码:
let fd = stdin().as_fd().try_clone_to_owned().unwrap();
let file = File::from(fd);
let meta = file.metadata().unwrap();
if meta.is_dir() {
let mut stdin_path = fs::canonicalize("/dev/stdin").unwrap();
println!({:?}", stdin_path);
// do something
}
我正在努力确保它也能在 Windows 上运行。由于 Windows 没有
std::os::fd::AsFd
、 as_fd
方法,而且也没有 /dev/stdin
,所以我不确定用于在 Windows 上实现相同功能的适当 API。有什么指导可以让它在 Windows 上运行吗?
Windows 等效项几乎相同,但使用句柄而不是文件描述符:
let handle = stdin().as_handle().try_clone_to_owned().unwrap();
let file = File::from(handle);
let meta = file.metadata().unwrap();
但是,这种情况非常罕见。为了测试这一点,我必须制作一个单独的 Rust 程序,该程序使用
OpenOptionsExt::custom_flags
打开一个文件(请参阅MS Learn 上的目录句柄)并将其提供给包含先前代码的程序。
use std::os::windows::fs::OpenOptionsExt;
use std::process::{Command, Stdio};
const FILE_FLAG_BACKUP_SEMANTICS: u32 = 0x02000000;
fn main() {
let file = std::fs::OpenOptions::new()
.read(true)
.custom_flags(FILE_FLAG_BACKUP_SEMANTICS)
.open("src")
.unwrap();
Command::new("first_program.exe")
.stdin(Stdio::from(file))
.spawn()
.unwrap()
.wait()
.unwrap();
}
看起来 Rust 标准库在需要读取符号链接或连接,或查询元数据时使用此功能,并且没有跨平台方式将目录返回为
File
。对于 shell,cmd 不允许您从目录重定向 stdin,PowerShell 甚至不允许您从文件重定向 stdin;你必须从Get-Content
通过管道传输它们。使用 Start-Process
的这个答案的解决方法也不适用于目录。
因此,如果您出于技术原因需要接受目录作为标准输入,则上述解决方案将起作用。但如果您只是想为程序的用户提供方便的快捷方式,那么这是不值得做的。最好说 Windows 上不支持此类操作,因为它不太可能是故意完成的。