我试图找出如何测试文件是否被重定向到自身,例如.\command.exe file1 > file1
在* nix世界中,我只是使用这样的东西:
// Language agnostic...
if (file_dev == out_dev && file_ino == out_ino) {
printf("%s\n", "same file!");
}
但在Windows中,如果我尝试这样做:
// This (language) is Go...
// create fileStat...
// now stat stdout
outStat, err := os.Stdout.Stat()
// error check
if os.SameFile(fileStat, outStat) {
fmt.Println("same file!")
}
...我收到IncorrectFunction
错误。
我读了这个问题(https://stackoverflow.com/a/21070042/2967113),从我收集的内容中你可以统计stdout
吗?
这是一个主要与语言无关的问题 - 我可以将任何内容翻译成Go(我使用的语言)。我最关心如何,使用Windows' ABI(API?),我会找到stdout被重定向到的地方。
答案 0 :(得分:1)
这个答案是特定于Windows的,但是当你标记“windows”时我觉得没问题。
我无法帮助Go,但在C / C ++中你可以这样做:
#include <tchar.h>
#include <Windows.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t chPath[MAX_PATH];
if (GetFinalPathNameByHandle(GetStdHandle(STD_OUTPUT_HANDLE), chPath, MAX_PATH, 0))
std::wcout << L"stdout = " << chPath << std::endl;
else
std::cout << "stdout not redirected" << std::endl;
return 0;
}
如果stdout是控制台句柄, GetFinalPathNameByHandle
将失败,但如果它被重定向到文件,它将返回文件路径。
答案 1 :(得分:1)
您可以致电HANDLE GetStdHandle( DWORD stdHandle )
with STD_INPUT_HANDLE
and STD_OUTPUT_HANDLE
打开文件句柄。
然后拨打DWORD GetFileType( HANDLE hFile )
to check if the returned type is FILE_TYPE_DISK
最后,请致电
获取文件路径名并比较名称的等效性。
答案 2 :(得分:0)
嗯,首先,我不认为你在UNIX-land中的方法实际会保护你。
当您的代码检查设备和inode时,shell已经已经截断了该文件。 它负责处理输出重定向,并且在程序开始之前执行此,以便为您的输出提供一个新文件。
我怀疑您在Windows中遇到同样的问题,cmd.exe
会在您的脚本开始运行之前截断您的文件。
话虽如此,我相信在某些时候你必须要相信用户知道他们在做什么: - )
另一种选择当然不是做输出重定向,而是要求输入和输出文件作为参数:
cmd.exe myscipt myscript
这样,您可以检测用户是否要写入输入文件(使用规范化的文件名或inode)并阻止它。
虽然仍然不会阻止用户做一些愚蠢的事情:
cmd.exe myscipt >myscript
在之前删除你的脚本,你有机会通知他们,他们应该提供两个参数而不是一个。
我认为最重要的是,如果用户确实输出了重定向,那么你的程序就无法在它太晚之前抓住它。