Marc Mutz - mmutz
Marc Mutz - mmutz

Reputation: 25283

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

In bash, I would use

[ -w ... ]

What's the equivalent for Windows batch files?

Upvotes: 7

Views: 5999

Answers (6)

Jacob Jarick
Jacob Jarick

Reputation: 63

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%

Upvotes: 0

Andry
Andry

Reputation: 2727

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.

Upvotes: 1

ghostdog74
ghostdog74

Reputation: 342273

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

Upvotes: 0

SketchBookGames
SketchBookGames

Reputation: 514

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.

Upvotes: -1

Leptonator
Leptonator

Reputation: 3499

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

Upvotes: 1

Álvaro González
Álvaro González

Reputation: 146350

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.

Upvotes: 3

Related Questions