파일 이름을 선택한 다음 이를 변수에 파이프하는 프로그램을 만들려고 합니다.
내 시도:
Dir /B "C:\Program Files (x86)\ServerMaster\Internals\Versions\Van1" | (set /p myVar= & set myVar)
사용 후에는 밖으로 나옵니다
myVar:1.14.4
계획은 들어가서 명령을 에코하는 것이었기 때문에 이렇게 만들었습니다.
@echo off
Dir /B "C:\Program Files (x86)\ServerMaster\Internals\Versions\Van1" | (set /p myVar= & set myVar)
echo e %myVar%
cmd /k
하지만 일어나는 일은 모두
e
내가 도대체 뭘 잘못하고있는 겁니까? 또한 FOR를 사용하여 이를 수행할 수 있는 방법이 있습니까?
답변1
내가 도대체 뭘 잘못하고있는 겁니까?
간단합니다. 작동할 수 없는 기술을 사용하려고 합니다. ;-) Windows 파이프가 작동하는 방식으로 인해 파이프된 명령 출력을 사용하여 상위 환경에서 환경 변수를 설정하는 것은 불가능합니다.
귀하의 스크립트는 명령 프로세스에서 실행 중입니다. 이를 상위라고 부를 수 있습니다.
Windows 파이프는 각각 별도의 환경 공간이 있는 두 개의 하위 명령 프로세스를 시작합니다. 파이프의 왼쪽은 첫 번째 자식에서 실행되고 오른쪽은 두 번째 자식에서 실행됩니다. 파이프는 첫 번째 자식의 출력을 두 번째 자식의 입력으로 보냅니다. SET /P
하위 프로세스에서 새 myVar 변수가 성공적으로 정의되고 명령 SET MYVAR
이 값을 표시합니다. 엄청난.
그러나 파이프가 종료되고 두 하위 프로세스가 모두 종료되며 관련 환경이 사라집니다. myVar 환경 값을 하위 파이프 프로세스에서 상위 환경으로 다시 전송할 수 있는 방법은 없습니다.
Windows 파이프 설계에는 메커니즘을 완전히 이해하지 못하는 사람을 혼란스럽게 만드는 놀라운 부작용이 많이 있습니다. 보다https://stackoverflow.com/q/8192318/1012053더 많은 정보를 위해서. 질문과 모든 답변을 읽어 보시기 바랍니다.
FOR로 이 작업을 수행할 수 있는 방법이 있나요?
예, 환경 변수에서 명령 출력을 캡처하는 적절한 방법은 특히 FOR /F
DavidPostill이 보여주는 것처럼 FOR를 이용하는 것입니다. 그의 코드에는 하나의 확실한 문제, 하나의 잠재적인 문제, 하나의 비효율성이 있지만.
USEBACKQ
명령의 출력을 처리할 때 사용할 필요가 없습니다 . '
백틱 대신 일반 작은따옴표를 사용하는 것이 더 간단합니다 .for /f %%F in ('yourCommand') do ...
오류는 echo myVar:%myVar%
FOR 루프 본문 내에서 사용하는 것입니다. myVar
라인을 구문 분석할 때 백분율 확장이 발생하고 전체 FOR 루프가 한 단계로 구문 분석되므로 루프가 실행되기 전에 존재했던 값이 표시됩니다 . 지연된 확장( )을 활성화 setlocal enableDelayedExpansion
한 다음 echo !myVar!
루프 내에 설정된 값을 보려면 를 사용해야 합니다.
또 다른 문제가 발생할 가능성이 있습니다. FOR /F는 값을 공백으로 구분된 토큰으로 구문 분석하고 첫 번째 토큰만 캡처합니다. 파일 이름에 공백이 포함되어 있으면 DELIMS 옵션을 사용하여 구분 기호를 지정하지 않는 한 전체 이름을 얻을 수 없습니다.
for /f "delims=" %%F in (....) do ....
DIR /B
하지만 꼭 and 를 사용할 필요는 없습니다 FOR /F
. 옵션 FOR
없이 간단히 바닐라 루프를 사용할 수 있습니다 /F
.
예를 들어 다음은 단순히 모든 파일을 나열합니다.
for %%F in ("C:\Program Files (x86)\ServerMaster\Internals\Versions\Van1\*") do echo %%~nxF
~nx
파일 이름과 확장자만 사용하고 드라이브와 폴더 경로는 삭제하도록 지정합니다 .
일반적으로 환경 변수를 사용할 필요가 없습니다. %%F
작업을 수행하려면 루프 내에서 FOR 변수를 사용하기만 하면 됩니다.
그러나 어떤 이유로 루프 외부의 값이 필요한 경우에는 확실히 다음을 수행할 수 있습니다.
for %%F in ("C:\Program Files (x86)\ServerMaster\Internals\Versions\Van1\*") do set "myVar=%%~nxF"
그러나 이는 반복된 마지막 파일만 캡처합니다. myVar 변수는 반복할 때마다 덮어쓰여집니다. 원래 디자인은 나열된 첫 번째 파일을 캡처했을 것입니다(작동할 수 있다고 가정). Van1 폴더에 단일 파일만 포함되어 있다는 사실을 알지 않는 한 둘 다 좋은 생각이 아닌 것 같습니다.
모든 파일을 변수로 캡처해야 하는 경우 의사 배열을 사용해야 합니다. Batch에는 공식적인 배열 개념이 없지만 쉽게 에뮬레이트할 수 있습니다. 웹에서 "배치파일 배열"을 검색하면 수많은 예제를 찾을 수 있습니다.