检查Windows文件是否重定向到自身

时间:2015-03-31 05:06:45

标签: windows stdout

我试图找出如何测试文件是否被重定向到自身,例如.\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被重定向到的地方。

3 个答案:

答案 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)

答案 2 :(得分:0)

嗯,首先,我不认为你在UNIX-land中的方法实际会保护你。

当您的代码检查设备和inode时,shell已经已经截断了该文件。 负责处理输出重定向,并且在程序开始之前执行此,以便为您的输出提供一个新文件。

我怀疑您在Windows中遇到同样的问题,cmd.exe会在您的脚本开始运行之前截断您的文件。

话虽如此,我相信在某些时候你必须要相信用户知道他们在做什么: - )

另一种选择当然不是输出重定向,而是要求输入和输出文件作为参数:

cmd.exe myscipt myscript

这样,您可以检测用户是否要写入输入文件(使用规范化的文件名或inode)并阻止它。

虽然仍然不会阻止用户做一些愚蠢的事情:

cmd.exe myscipt >myscript

之前删除你的脚本,你有机会通知他们,他们应该提供两个参数而不是一个。

我认为最重要的是,如果用户确实输出了重定向,那么你的程序就无法在它太晚之前抓住它。