还是简单说几句吧。
重定向符号的分析必然优先于前面的语句命令,这是无需争议的。
重定向输出>和>>都会用CreateFile函数打开目标文件,dwDesiredAccess参数为GENERIC_WRITE,dwShareMode参数为FILE_SHARE_READ,所以打开之后文件是只读的,无法写入。(详见批处理技术内幕:重定向与句柄)
for /f也会用CreateFile函数打开目标文件,dwDesiredAccess参数为GENERIC_READ,dwShareMode参数为FILE_SHARE_READ | FILE_SHARE_DELETE,如果文件已经在重定向的时候被打开,则CreateFile函数调用会失败。- (for /f %%a in (a.txt) do xxx)>>a.txt
复制代码 代码运行后的错误信息是“系统找不到文件 a.txt。”,与a.txt不存在的错误信息是一样的,但是正确的原因应该是“另一个程序正在使用此文件,进程无法访问。 ”
CMD的错误处理真是渣渣,CreateFile函数失败以后也不调用GetLastError看看是什么原因,直接说系统找不到文件。
至于type命令,用CreateFile函数打开目标文件时,dwDesiredAccess参数为GENERIC_READ,dwShareMode参数为FILE_SHARE_READ | FILE_SHARE_WRITE,所以即使文件已经在重定向的时候被打开,CreateFile函数调用也不会失败。
可以用C程序验证如下:- #include <stdio.h>
- #include <windows.h>
-
- // by Demon
- // http://demon.tw
-
- int main()
- {
- HANDLE hFile;
-
- hFile = CreateFile(
- "a.txt",
- GENERIC_WRITE,
- // 重定向的dwShareMode
- FILE_SHARE_READ,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- if (hFile == INVALID_HANDLE_VALUE) {
- printf("1: %d\n", GetLastError());
- }
-
-
- hFile = CreateFile(
- "a.txt",
- GENERIC_READ,
- // FOR /F命令的dwShareMode
- FILE_SHARE_READ | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- if (hFile == INVALID_HANDLE_VALUE) {
- printf("2: %d\n", GetLastError());
- }
-
- hFile = CreateFile(
- "a.txt",
- GENERIC_READ,
- // TYPE命令的dwShareMode
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- if (hFile == INVALID_HANDLE_VALUE) {
- printf("3: %d\n", GetLastError());
- }
-
- return 0;
- }
复制代码
|