7

In bash, I would use

[ -w ... ]

What's the equivalent for Windows batch files?

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
  • Possible duplicate of [Best way to check if directory is writable in BAT script?](https://stackoverflow.com/questions/7272850/best-way-to-check-if-directory-is-writable-in-bat-script) – darthbith Jul 01 '19 at 20:46
  • @darthbith how can it be a duplicate if it predates the presumably-duplicated question by more than a year? – Marc Mutz - mmutz Jul 04 '19 at 09:07
  • Then maybe the duplicate should go the other way ¯\_(ツ)_/¯ That one has a better answer though, IMO – darthbith Jul 04 '19 at 15:14

6 Answers6

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.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
  • +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. – Joey Jan 04 '10 at 15:16
  • This just amazing how an accepted stackoverflow answer become incorrect after a time pass: https://stackoverflow.com/questions/1999988/how-to-check-whether-a-file-dir-is-writable-in-batch-scripts/59884789#59884789 – Andry Jan 03 '22 at 04:01
  • @Andry 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. – Álvaro González Jan 03 '22 at 09:19
  • @Á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. – Andry Jan 03 '22 at 16:11
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://stackoverflow.com/a/10520609/175063

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
    )
)
Community
  • 1
  • 1
Leptonator
  • 3,379
  • 2
  • 38
  • 51
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.

Andry
  • 2,273
  • 29
  • 28
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
Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
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%
Jacob Jarick
  • 63
  • 1
  • 7
-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.

SketchBookGames
  • 464
  • 8
  • 14