Windows Batch: busca a primeira ocorrência em uma listagem de variáveis

1

Estou trabalhando em um arquivo de comando em lote do Windows 7 (drv.bat) que tenta mapear uma unidade que já está sendo executada. Net use o listaria como um mapeamento de unidade, portanto, errorlevel é elevado para 2 neste caso. Por isso, a seguir, é exibida uma listagem das unidades de rede atualmente disponíveis.

@echo off
setlocal
net use A: \computername\sharename /persistent:No
ECHO.%ERRORLEVEL%
IF %ERRORLEVEL% NEQ 0 for %%p in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if not exist %%p:\nul echo Drive: %%p
...    
endlocal

Isso me dá uma listagem assim:

Drive: F
Drive: G
Drive: J
Drive: M
Drive: R
Drive: S
Drive: T
Drive: X
Drive: Y
Drive: Z

Meu objetivo é buscar a primeira letra de unidade disponível. A disponibilidade da letra da unidade pode variar dependendo de quantos PCs se conectam a este grupo de trabalho. Então, esse lote deve sempre atribuir a primeira ocorrência nessa listagem. Exatamente neste momento estou perdido. Não se preocupe com o resto até que não haja mais unidades disponíveis.

Espero que alguém possa me ajudar a dar um passo adiante.

O feedback é muito apreciado.

Depois de algumas horas, eu tenho esse código muito instável trabalhando um pouco. Eu prefiro muito mais e aceito a resposta da @JosefZ, já que acho a versão dele uma solução muito elegante que atende todas as minhas necessidades - obrigado.

@echo off
net use B: \OQO-PC\OQO-SYSTEM /persistent:No
IF %ERRORLEVEL% EQU 0 goto end
::rem info: Drive G: for CD-ROM removed in list
setlocal enabledelayedexpansion
SET DRVLSTV=
echo [\OQO-PC\OQO-SYSTEM] 
ECHO -------------------------------------------
FOR %%f IN (A B C D E F H I J K L M N O P Q R S T U V W X Y Z) DO IF not exist %%f:\nul @set DRVLSTV=!DRVLSTV! %%f:
FOR /F "tokens=1 delims= " %%d IN ("%DRVLSTV%") DO IF %%d NEQ " " (net use %%d \OQO-PC\OQO-SYSTEM /persistent:No)
echo Drive got remapped to the first available drive
endlocal
:end
::net use
::pause
    
por snahl 01.11.2015 / 21:39

2 respostas

1

Aqui está outra abordagem:

@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
rem get list of disk letters in use
set "_inUseDisks="
for /f "tokens=2 delims==" %%D in ('
  wmic logicaldisk get caption /value
  ') do (
    for /F "delims=:" %%d in ("%%D") do (
      set "_inUseDisks=!_inUseDisks! %%d"
    )
)
echo Disk letters in use %_inUseDisks%
rem get first available disk letter
set "_available="
for %%p in (C D E F G H I J K L M N O P Q R S T U V W X Y Z A B) do (
  set "_test=!_inUseDisks:%%p=!"
  if "!_test!"=="%_inUseDisks%" (
    if not defined _available set "_available=%%p"
    rem goto :gotletter
  )
)
:gotletter
if "%_available%"=="" (
  echo No available disk letter
) else (
  rem echo First available disk letter: %_available%:
  echo net use %_available%: \computername\sharename /persistent:No
)

No script acima, os loops for são

  • %%D para recuperar o valor caption ;
  • %%d para remover o retorno de carro final no valor retornado: wmic behavior: cada linha de saída termina com 0x0D0D0A ( <CR><CR><LF> ) em vez de comum 0x0D0A ( <CR><LF> ) .

Veja WMIC e FOR /F de Dave Benham: uma correção para o problema <CR> à direita

  • ordem das letras no ciclo %%p alterado;
  • operacional net use é meramente exibido para fins de depuração; remova echo não antes que depurado.

Próximos recursos (leitura obrigatória, incompleta):

por 02.11.2015 / 17:03
0
@echo off
setlocal EnableDelayedExpansion
pushd \computername\sharename
for /f "delims=" %%u in ('cd') do set av_unit=%%u && echo !av_unit:\ =!
popd

EnableDelayedExpansion permite a manipulação de variáveis dentro da instrução for , que remove apenas a barra invertida e o espaço da pasta raiz da unidade.

    
por 02.11.2015 / 15:59