Лучший способ проверить, доступен ли каталог для записи в скрипте BAT? - PullRequest
7 голосов
/ 01 сентября 2011

Как проверить, доступен ли для записи исполняемый пользователь из пакетного сценария?

Вот что я пробовал до сих пор:

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

4 голосов
/ 01 сентября 2011

Определенно запустив команду против нее, чтобы определить, является ли ее отказ простым способом сделать это. Вы также можете использовать 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.
3 голосов
/ 01 сентября 2011

Вы можете написать copy %0 foo, чтобы скопировать сам пакетный файл.
Это всегда будет существовать.

Не забудьте впоследствии удалить файл и убедиться, что вы не перезаписываете существующий файл.под этим именем.

Должен быть лучший способ сделать это, но я не знаю ни одного.

РЕДАКТИРОВАТЬ : Еще лучше, попробуйте mkdir foo.
В случае, если пакетный файл запускается из сети (или если он очень большой), это может быть быстрее.

1 голос
/ 31 января 2012

Я обнаружил, что выполнение 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 и, кажется, работает надежно.

1 голос
/ 02 сентября 2011
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%
0 голосов
/ 28 ноября 2018

Расширение ответа Mechaflash , которое решает проблему перезаписи файла путем создания уникального имени файла для файла «testing».

@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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...