检查目录在BAT脚本中是否可写的最佳方法是什么?

时间:2011-09-01 15:45:03

标签: windows permissions batch-file

如何检查执行用户是否可以从批处理脚本写入目录?

这是我到目前为止所尝试的内容:

> cd "%PROGRAMFILES%"

> echo. > foo
Access is denied.
> echo %ERRORLEVEL%
0

好的,那么......

> copy NUL > foo
Access is denied.
> echo %ERRORLEVEL%
0

不是吗?那么......

> copy foo bar
Access is denied.
        0 file(s) copied.
> echo %ERRORLEVEL%
1

这样可行,但如果文件不存在则会中断。

我已经阅读了一些关于内部命令没有设置ERRORLEVEL的内容,但copy显然似乎在最后一种情况下这样做了。

5 个答案:

答案 0 :(得分:4)

绝对运行一个命令来查找它是否是一种简单的方法。您还可以使用CACLS准确查找权限是什么或不是。这是一个样本。

在CMD类型CACLS /?

CACLS "filename"将为您提供文件允许的当前权限。 R =读,W =写,C =变化(与写入相同?),F =完全访问。

编辑:你也可以使用目录名。

所以要做检查,你会:

FOR /F "USEBACKQ tokens=2 delims=:" %%F IN (`CACLS "filename" ^| FIND "%username%"`) DO (
 IF "%%F"=="W" (SET value=true && GOTO:NEXT)
 IF "%%F"=="F" (SET value=true && GOTO:NEXT)
 IF "%%F"=="C" (SET value=true && GOTO:NEXT)
 SET value=false
)
ECHO This user does not have permissions to write to file.
GOTO:EOF
:NEXT
ECHO This user is able to write to file.

答案 1 :(得分:3)

您可以编写copy %0 foo来复制批处理文件本身 这将永远存在。

请记住之后删除该文件,并确保您没有用该名称覆盖现有文件。

应该有更好的方法来做到这一点,但我不知道。

编辑:更好的是,试试mkdir foo 如果批处理文件在网络上运行(或者如果它非常大),这可能会更快。

答案 2 :(得分:1)

set testdir=%programfiles%
set myguid={A4E30755-FE04-4ab7-BD7F-E006E37B7BF7}.tmp
set waccess=0
echo.> "%testdir%\%myguid%"&&(set waccess=1&del "%testdir%\%myguid%")
echo write access=%waccess%

答案 3 :(得分:1)

我发现在批处理文件中执行copy会向STDERR回显错误,但保持%ERRORLEVEL%不变(仍为0)。所以解决方法是将命令与set的条件执行结合起来。

copy /Y NUL "%FOLDER%\.writable" > NUL 2>&1 && set WRITEOK=1
IF DEFINED WRITEOK ( 
  rem ---- we have write access ----
  ...
 ) else (
  rem ---- we don't ----
  ...
)

这是在XP和7上测试的,似乎可靠地工作。

答案 4 :(得分:0)

Mechaflash答案的扩展名,并通过为“测试”文件生成唯一的文件名来解决覆盖文件的问题。

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "a=%~1"
SET "b="
SET "g=0"
:a
SET "c= `1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,.~!@#$%%^&()_+QWERTYUIOP{}ASDFGHJKLZXCVBNM"
SET /A "d=0, e=1"
:b
IF "!c!" NEQ "" (
    IF "!c:~%d%,1!" NEQ "" (
        IF EXIST "!a!\!b!!c:~%d%,1!" (
            SET "c=!c:~0,%d%!!c:~%e%!"
        ) ELSE (
            SET /A "d=!d!+1, e=!e!+1"
        )
        GOTO :b
    )
)
IF "!c!" EQU "" (
    SET "c= `1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,.~!@#$%%^&()_+QWERTYUIOP{}ASDFGHJKLZXCVBNM"
    :c
    IF "!c!" NEQ "" (
        IF "!c:~%d%,1!" NEQ "" (
            SET /A "d=!d!+1"
            GOTO :c
        )
    )
    SET /A "d=!d!-1"
    SET /A "f=%RANDOM%*!d!/32768"
    SET "b=!b!!c:~%f%,1!"
    GOTO :a
) ELSE (
    SET /A "d=!d!-1"
    SET /A "f=%RANDOM%*!d!/32768"
    SET "b=!b!!c:~%f%,1!"
)
((ECHO EXIT>"!a!\!b!" && SET "g=1") & IF EXIST "!a!\!b!" DEL /F "!a!\!b!") >NUL 2>&1
ENDLOCAL & (SET "a=%g%")
IF "%a%" EQU "1" ECHO TRUE

%~1是输入目录)
编辑:如果您想要一个更安全的选择

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "a=%~1"
SET "b="
SET "g=0"
:a
SET "c= `1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,.~!@#$%%^&()_+QWERTYUIOP{}ASDFGHJKLZXCVBNM"
SET /A "d=0, e=1"
:b
IF "!c!" NEQ "" (
    IF "!c:~%d%,1!" NEQ "" (
        IF EXIST "!a!\!b!!c:~%d%,1!" (
            SET "c=!c:~0,%d%!!c:~%e%!"
        ) ELSE (
            SET /A "d=!d!+1, e=!e!+1"
        )
        GOTO :b
    )
)
IF "!c!" EQU "" (
    SET "c= `1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,.~!@#$%%^&()_+QWERTYUIOP{}ASDFGHJKLZXCVBNM"
    :c
    IF "!c!" NEQ "" (
        IF "!c:~%d%,1!" NEQ "" (
            SET /A "d=!d!+1"
            GOTO :c
        )
    )
    SET /A "d=!d!-1"
    SET /A "f=%RANDOM%*!d!/32768"
    SET "b=!b!!c:~%f%,1!"
    GOTO :a
) ELSE (
    SET /A "d=!d!-1"
    SET /A "f=%RANDOM%*!d!/32768"
    SET "b=!b!!c:~%f%,1!"
)
IF EXIST "!a!\!b!" (
    SET "b=!b:~0,-1!"
    GOTO :a
) ELSE (
    ((ECHO EXIT>"!a!\!b!" && SET "g=1") & IF EXIST "!a!\!b!" DEL /F "!a!\!b!") >NUL 2>&1
)
ENDLOCAL & (SET "a=%g%")
IF "%a%" EQU "1" ECHO TRUE