问题描述
在尝试对此类文件执行任何操作之前,我需要知道这一点.
I need to know that before any attempt to do anything with such file.
推荐答案
不确定锁定的目录(Windows 有吗?)
Not sure about locked directories (does Windows have that?)
但是检测一个文件是否正在被另一个进程写入并不困难.
But detecting if a file is being written to by another process is not difficult.
@echo off
2>nul (
>>test.txt echo off
) && (echo file is not locked) || (echo file is locked)
我使用另一个窗口中的以下测试脚本来锁定文件.
I use the following test script from another window to place a lock on the file.
(
>&2 pause
) >> test.txt
当我从一个窗口运行第二个脚本,然后从第二个窗口运行第一个脚本时,我收到锁定"消息.在第一个窗口中按 后,如果我重新运行第一个脚本,则会收到已解锁"消息.
When I run the 2nd script from one window and then run the 1st script from a second window, I get my "locked" message. Once I press <Enter>
in the 1st window, I get the "unlocked" message if I rerun the 1st script.
说明
每当命令的输出被重定向到文件时,当然必须打开文件以进行写访问.Windows CMD 会话将尝试打开该文件,即使该命令没有产生任何输出.
Whenever the output of a command is redirected to a file, the file of course must be opened for write access. The Windows CMD session will attempt to open the file, even if the command does not produce any output.
>>
重定向操作符以追加模式打开文件.
The >>
redirection operator opens the file in append mode.
所以 >>test.txt echo off
将尝试打开文件,它不会向文件写入任何内容(假设 echo 已经关闭),然后关闭文件.该文件未以任何方式修改.
So >>test.txt echo off
will attempt to open the file, it writes nothing to the file (assuming echo is already off), and then it closes the file. The file is not modified in any way.
大多数进程在打开文件进行写访问时都会锁定文件.(有些操作系统系统调用允许在共享模式下打开文件进行写入,但这不是默认设置).因此,如果另一个进程已经锁定了test.txt"以进行写入,则重定向将失败,并将以下错误消息发送到 stderr - 该进程无法访问该文件,因为它正被另一个进程使用.".重定向失败时也会生成错误代码.如果命令和重定向成功,则返回成功码.
Most processes lock a file whenever they open a file for write access. (There are OS system calls that allow opening a file for writing in a shared mode, but that is not the default). So if another process already has "test.txt" locked for writing, then the redirection will fail with the following error message sent to stderr - "The process cannot access the file because it is being used by another process.". Also an error code will be generated upon redirection failure. If the command and the redirection succeed, then a success code is returned.
简单地向命令添加 2>nul
不会阻止错误消息,因为它重定向命令的错误输出,而不是重定向.这就是为什么我将命令括在括号中,然后将错误输出重定向到括号外的 nul.
Simply adding 2>nul
to the command will not prevent the error message because it redirects the error output for the command, not the redirection. That is why I enclose the command in parentheses and then redirect the error output to nul outside of the parens.
所以错误信息被有效地隐藏了,但错误代码仍然传播到括号之外.标准的 Windows &&
和 ||
运算符用于检测括号内的命令是成功还是失败.大概 echo off
永远不会失败,所以唯一可能的失败原因是重定向失败.很可能由于锁定问题而失败,但从技术上讲,失败可能还有其他原因.
So the error message is effectively hidden, but the error code is still propagated outside of the parens. The standard Windows &&
and ||
operators are used to detect whether the command inside the parens was successful or failed. Presumably echo off
will never fail, so the only possible reason for failure would be the redirection failed. Most likely it fails because of a locking issue, though technically there could be other reasons for failure.
除非使用 ||
运算符,否则 Windows 不会在重定向失败时将 %ERRORLEVEL% 动态变量设置为错误,这是一个奇怪的功能".(请参阅Windows 中的文件重定向和%errorlevel%).所以 ||
操作符必须在某个低级别读取返回的错误代码,而不是通过 %ERRORLEVEL% 变量.
It is a curious "feature" that Windows does not set the %ERRORLEVEL% dynamic variable to an error upon redirection failure unless the ||
operator is used. (See File redirection in Windows and %errorlevel%). So the ||
operator must read the returned error code at some low level, not via the %ERRORLEVEL% variable.
使用这些技术来检测重定向失败在批处理上下文中非常有用.它可用于建立允许在并行进程中序列化多个事件的锁.例如,它可以使多个进程在同一"时间安全地写入同一个日志文件.Windows 下如何共享日志文件?
Using these techniques to detect redirection failure can be very useful in a batch context. It can be used to establish locks that allow serialization of multiple events in parallel processes. For example, it can enable multiple processes to safely write to the same log file at the "same" time. How do you have shared log files under Windows?
编辑
关于锁定的文件夹.我不确定 Windows 是如何实现这一点的,也许是用锁来实现的.但是如果一个进程有一个涉及该文件夹的活动目录,则该文件夹不能被重命名.使用
Regarding locked folders. I'm not sure how Windows implements this, perhaps with a lock. But if a process has an active directory involving the folder, then the folder cannot be renamed. That can easily be detected using
2>nul ren folderName folderName && echo Folder is NOT locked || echo folder is LOCKED
编辑
我后来了解到 (call )
(with a space) 是一个非常快的命令,没有副作用,在 ERRORLEVEL 设置为 0 时保证成功.并且(call)
(没有空格) 是一个没有副作用的快速命令,它保证以 ERRORLEVEL 1 失败.
I have since learned that (call )
(with a space) is a very fast command without side effects that is guaranteed to succeed with ERRORLEVEL set to 0. And (call)
(without a space) is a fast command without side effects that is guaranteed to fail with ERRORLEVEL 1.
所以我现在使用以下命令来检查文件是否被锁定:
So I now use the following to check if a file is locked:
2>nul (
>>test.txt (call )
) && (echo file is not locked) || (echo file is locked)
这篇关于如果给定的文件或目录被锁定(由任何进程使用),如何在命令行中检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!