How to check whether a file/dir is writable in batch scripts
Asked Answered
A

6

7

In bash, I would use

[ -w ... ]

What's the equivalent for Windows batch files?

Adamsun answered 4/1, 2010 at 14:50 Comment(3)
Possible duplicate of Best way to check if directory is writable in BAT script?Janenejanenna
@Janenejanenna how can it be a duplicate if it predates the presumably-duplicated question by more than a year?Adamsun
Then maybe the duplicate should go the other way ¯_(ツ)_/¯ That one has a better answer though, IMOJanenejanenna
K
3

As far as I know, you can find out whether the file exists or not, but there's no way to know if it's writeable, apart from trying to write on it. It's not only a matter of not having the R flag; network and NTFS permissions are involved as well (and probably group policies too).

If you can rewrite your code, you can capture the return code of the write operation trough the errorlevel.

Kajdan answered 4/1, 2010 at 15:2 Comment(4)
+1 for mentioning permissions. It's definitely not just a matter of the read-only flag which would be trivial to check with %~ax or something like that.Marenmarena
This just amazing how an accepted stackoverflow answer become incorrect after a time pass: #2000488Prude
@Prude Can you please elaborate on what information in this answer has become outdated? Unless I'm missing something, the link you've shared only shows how to attempt to write on a file in order to determine if it succeeds.Sn
@Álvaro González It does not attempt to write as long as access times does not change, so there's is a way o know if it's writable w/o actually trying to write.Prude
N
1

Sorry folks for chiming in here..

This may not be 100% what you are looking for, but I have used this with in-use log files for Apache Tomcat and it works absolutely perfectly.

Thanks to @dbenham for his awesome code! https://mcmap.net/q/245206/-how-to-check-in-command-line-if-a-given-file-or-directory-is-locked-used-by-any-process

SETLOCAL ENABLEDELAYEDEXPANSION
REM TOMCAT LOGS
FOR /r "D:\logs" %%X IN (*) DO (
    SET FileName=%%~nxX
    2>nul (   >>D:\logs\!FileName!" (call )) && (
    REM DO STUFF HERE
    SET ModDt=%%~tX
    FOR /f "tokens=1-3 delims=.:/ " %%j IN ("!ModDt!") DO SET FDate=%%l-%%j-%%k&Set RegDate=%%j-%%k-%%l
    IF "%CurrentDate%" NEQ "!FDate!" (
        IF %%~zX GTR 0 (
            ECHO ARCHIVING "D:\logs\!FileName!" >> %logfile%
            7za.exe -tzip -y a "D:\Zips\%COMPUTERNAME%-Tomcat-!RegDate!-compressed.zip" "D:\logs\!FileName!" && (
            DEL /Q "D:\logs\!FileName!"
            ) || (
                if "%ERRORLEVEL%" == "2" (
                    echo Zipping failed ^(exit status %ERRORLEVEL%^).  Trying again in 5 seconds...
                ) else (
                    echo Zip completed with warnings ^(most likely because a file was locked by another
                    echo process and had to be skipped^).  Trying again in 5 seconds...
                )
                del "D:\Zips\%COMPUTERNAME%-Tomcat-!RegDate!-compressed.zip" >NUL 2>&1
                PING 0.0.0.0 -n 6 -w 1000 >NUL
            )
        )
    )
    REM END OF UNLOCKED ZONE
    ) || (
    ECHO FILE IS LOCKED
    )
)
Nisse answered 18/1, 2016 at 8:19 Comment(0)
P
1

This is old but I didn't found it here:

lock.bat

(
  echo.123
  pause
) > "1.txt"

test.bat

move /Y "1.txt" "1.txt" >nul 2>nul
echo.%ERRORLEVEL%

The move does not change a file create/change/access times.

https://www.dostips.com/forum/viewtopic.php?t=5542


To check the access rights to a directory you can go the same way with the rename command:

rename "path\1.txt" "1.txt" >nul 2>nul
echo.%ERRORLEVEL%

To test it just add for path\ - deny all for Everyone.

Prude answered 23/1, 2020 at 18:14 Comment(0)
V
0

you can do it like this using vbscript

Set objFS=CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile = objArgs(0)
Set objFile = objFS.GetFile(strFile)
If Not objFile.Attributes And 1 Then
   WScript.Echo "The file is Read/Write."
Else
   WScript.Echo "The file is Read-only."
End If

save as check.vbs and on command line

c:\test> cscript //nologo check.vbs myfile
Votaw answered 4/1, 2010 at 14:58 Comment(1)
ACLs are involved too. See Álvaro's answer.Marenmarena
L
0

The most reliable method I have found is to copy NUL to a file in the target directory.

This will exit with 1 if the directory does not exist or if the directory is not writable by the current user.

I use /B as NUL is binary and /Y to overwrite the existing file.

copy /Y /B NUL "c:\test\test.txt"
echo %ERRORLEVEL%
Lagas answered 4/8, 2023 at 3:23 Comment(0)
M
-1
ls -l foo.txt

outputs -r--r--r-- for a not writable file outputs -rw-r--r-- for a writable file

you could store the value and check if the 3rd character is "w" for writable or "-" for not writable.

using some syntax like %myVar:~2,1% in a conditional statement.

not sure how OS dependent this would be.

Malachy answered 23/9, 2016 at 20:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.