Check from a batch if a disk is mounted

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
sambul35
Posts: 192
Joined: 18 Jan 2012 10:13

Check from a batch if a disk is mounted

#1 Post by sambul35 » 19 Jun 2016 19:24

I need to check when running a batch, if a certain disk is mounted. When I use this code, it works:

Code: Select all

@echo off
if exist K:\nul echo "The disk is mounted"
exit /b

However, this code doesn't work:

Code: Select all

@echo off
set "dsk=K:\Files"
if exist %dsk:~0,3%nul echo "The disk is mounted"
exit /b

:: error
The system cannot find the drive specified.

Is there a short workaround to check if a disk specified by a variable is mounted? Since IF EXIST doesn't seem to work with variables, it won't work inside a FOR loop either with %%A parameter to loop through all possible drive letters - right?

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Check from a batch if a disk is mounted

#2 Post by penpen » 20 Jun 2016 00:41

Your above code works on my Win XP, and 8.1, without this error message (also when using for variables).

This (hopefully) might help you:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion
set "dsk=K:\Files"
for %%a in (A B C D E F G H I J %dsk:~0,1% L M N O P Q R S T U V W X Y Z) do 2>nul (
   >nul vol "%%~a:"
) && (
   echo Volume %%~a: is mounted.
) || (
   echo Volume %%~a: is not mounted.
)
endlocal
exit /b


penpen

sambul35
Posts: 192
Joined: 18 Jan 2012 10:13

Re: Check from a batch if a disk is mounted

#3 Post by sambul35 » 20 Jun 2016 06:19

Sorry, there was a typo in my above snippet, it does work as posted. Below is the corrected version, it might show a bug in IF EXIST command. Your above code also doesn't work properly, if DelayedExpension is used, which seems expected in FOR loop options as discussed elsewhere, unless its possible to modify it.

Code: Select all

@echo off
setlocal EnableDelayedExpansion
set "dsk=K:\Files"
echo !dsk:~0,3!nul %dsk:~0,3%nul
call :disk
exit /b

:disk
set "dsk=L:\Files" & if not exist !dsk:~0,3!nul (echo "The disk is not mounted")
exit /b

:: Output
K:\nul K:\nul
'3nul' is not recognized as an internal or external command,
operable program or batch file.


It likely also means, DelayedExpansion in the above code isn't required. At times its hard to figure out, if its needed or not, especially in functions, only tests can show. :) My real code is more complex, but I tested it now without delayed expansion, and it works. Thanks for pointing in the right direction.

Compo
Posts: 600
Joined: 21 Mar 2014 08:50

Re: Check from a batch if a disk is mounted

#4 Post by Compo » 20 Jun 2016 08:40

Just an alternative:

Code: Select all

@Echo Off
For /L %%a In (67 1 90) Do (Cmd/C Exit/B %%a&Call :disk %%=EXITCODEASCII%%)
Timeout 5 1>Nul
Exit/B

:disk
MountVol|Find "%1:\">Nul||Echo("%~1: is not mounted"

Squashman
Expert
Posts: 4486
Joined: 23 Dec 2011 13:59

Re: Check from a batch if a disk is mounted

#5 Post by Squashman » 20 Jun 2016 08:56

penpen wrote:Your above code works on my Win XP, and 8.1, without this error message (also when using for variables).

Ditto for Windows 7.

sambul35
Posts: 192
Joined: 18 Jan 2012 10:13

Re: Check from a batch if a disk is mounted

#6 Post by sambul35 » 20 Jun 2016 11:07

Compo wrote:Just an alternative...

Interesting solution, I couldn't find on the web. Can you explain in a bit more details how it works, and why did you put these numbers in the FOR options?

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Check from a batch if a disk is mounted

#7 Post by aGerman » 20 Jun 2016 12:35

if you search the forum for EXITCODEASCII you'll find quite a lot.
If the errorlevel value is in the range of printable ASCII characters then also the %=EXITCODEASCII% variable is defined and contains the related character.

Code: Select all

cmd /c exit /b 67
echo %=exitcodeascii%
cmd /c exit /b 90
echo %=exitcodeascii%

This code snippet prints C and Z.
(Have a look at any ASCII table that you may find ...)

Regards
aGerman

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Check from a batch if a disk is mounted

#8 Post by penpen » 20 Jun 2016 15:46

sambul35 wrote:Below is the corrected version, it might show a bug in IF EXIST command. Your above code also doesn't work properly, if DelayedExpension is used
This is no issue with FOR or IF EXIST.
After the (normal) expansion phase the line is tokenized and the delimiter ',' (comma) signals the end of the second comparator string.
It should work, if you escape the comma (so it is not handled as a special character (delimiter); FOR loop analougous):

Code: Select all

@echo off
setlocal EnableDelayedExpansion
set "dsk=K:\Files"
echo !dsk:~0,3!nul %dsk:~0,3%nul
call :disk
for %%a in (!dsk:~0^,1!) do 2>nul (
   >nul vol "%%~a:"
) && (
   echo Volume %%~a: is mounted.
) || (
   echo Volume %%~a: is not mounted.
)
exit /b

:disk
if not exist !dsk:~0^,3!nul (echo "The disk !dsk:~0,3! is not mounted")
exit /b


penpen

sambul35
Posts: 192
Joined: 18 Jan 2012 10:13

Re: Check from a batch if a disk is mounted

#9 Post by sambul35 » 20 Jun 2016 17:40

@aGerman

Now it's getting clear looking at this ASCII Table. Still I added the Compo's snippet to my notebook's Tricks section. :)

@penpen

Thanks, now it works OK. I wonder, why with some commands like ECHO the same delayed expended variable works normally, and with others like IF EXIST it doesn't without escapes? At 1st look IF EXIST doesn't require tokenization in contrast with FOR loop...

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Check from a batch if a disk is mounted

#10 Post by penpen » 21 Jun 2016 06:21

sambul35 wrote:Thanks, now it works OK. I wonder, why with some commands like ECHO the same delayed expended variable works normally, and with others like IF EXIST it doesn't without escapes?
The command line interpreter (cli) splits actual statement into tokens to detect which statement has to be executed:
This is where the ',' seperates the tokens and fails.
You may use doublequotes instead of '^' to prevent the filename to be split into parts on delimiters:

Code: Select all

if not exist "!dsk:~0,3!nul" echo no 
It may be more intuitive.

The echo command is split into tokens, too.
But if no special case is detected then tokenization of the argument string is discarded and the complete argument string is interpreted as the print_string token:

Code: Select all

@echo off
:: print actual echo state: statement ::= keyword("echo")
echo

:: print echo help screen: statement ::= keyword("echo") token("/?") token*
echo ^ =;, /? abcdefg

:: switch echo state to on: statement ::= keyword("echo") token("ON")
echo              ON

:: switch echo state to off: statement ::= keyword("echo") token("OFF")
echo                        OFF

:: no other case: statement ::= keyword("echo") token(print_string("ON OFF /?"))
echo ON OFF /?

:: prove that echo is a token, and the right is handled as one token (first comma disappears):
echo,a,b

::force the string to be interpreted as a print_string: well THAT is hard to explain;
:: it seems that compount statements have a higher priority to be recognized although there is no compount statement present here...
:: but could also be caused by other side effects - so this is just a guess
echo(/?

:: similar (guessed) explaination for these:
echo\/?
echo//?
echo./?
:: ...
goto :eof

sambul35 wrote:At 1st look IF EXIST doesn't require tokenization in contrast with FOR loop...
Why should the if exist doesn not need tokenization?
If you use the statement "if not exist filename statement" then "if", "exist", filename, and statement are all tokens (from the parsers point of view).


penpen

Post Reply