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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7272850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 17:58:38  来源:igfitidea点击:

Best way to check if directory is writable in BAT script?

windowspermissionsbatch-file

提问by batshcrazy

How can I check whether a directory is writable by the executing user from a batch script?

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

Here's what I've tried so far:

这是我迄今为止尝试过的:

> cd "%PROGRAMFILES%"

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

Ok, so how about...

好吧,那怎么样...

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

Not that either? Then what about...

也不是吗?那怎么办...

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

This works, but it breaks if the file doesn't exist.

这有效,但如果文件不存在,它会中断。

I've read something about internal commands not setting ERRORLEVEL, but copyobviously seems to do so in the last case.

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

回答by Mechaflash

Definitely running a command against it to find if its denied is the easy way to do it. You can also use CACLS to find exactly what the permissions are or aren't. Here's a sample.

肯定会针对它运行一个命令,以确定它是否被拒绝是最简单的方法。您还可以使用 CACLS 来准确查找权限是什么或不是什么。这是一个示例。

In CMD type CACLS /?

在 CMD 类型中 CACLS /?

CACLS "filename"will give you what the current permissions is allowed on the file. R = Read, W = Write, C = Change (same as write?), F = Full access.

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

EDIT: You can use directory name as well.

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

So to do a check, you would:

因此,要进行检查,您将:

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.

回答by SLaks

You can write copy %0 footo copy the batch file itself.
This will always exist.

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

Remember to delete the file afterwards, and to make sure that you aren't overwriting an existing file by that name.

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

There ought to be a better way to do this, but I don't know of any.

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

EDIT: Better yet, try mkdir foo.
In case the batch file is running off a network (or if it's very large), this may be faster.

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

回答by Anders

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%

回答by Anders

i found that executing copywithin the batch file echoed an error to STDERR, but left %ERRORLEVEL%untouched (still 0). so the workaround was to combine the command with a conditional execution of set.

我发现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 ----
  ...
)

this is tested on XP and 7 and seems to work reliably.

这在 XP 和 7 上进行了测试,似乎可以可靠地工作。

回答by Leo Miao

An extension to Mechaflash's answer, and solves the problem of overwriting the file by generating a unique filename for the "testing" file.

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

(%~1is the input directory)
EDIT: If you want a more safe option

%~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