2009-03-27 62 views
17

Tôi có một tập tin thực thi mà khởi tạo các biến qua SET bên trong một vòng lặp for, đối với một bộ các tập tin trên đĩa:biến Batch file khởi tạo trong một vòng lặp for

for %%f in (%MYTARGETDIR%\*config.xml) do (
    SET TMPFILE=%%F.tmp 

    echo In loop %TMPFILE% 
) 

echo End loop %TMPFILE% 

khi tôi chạy này trong một thương hiệu lệnh mới shell (không có TMPFILE được định nghĩa) echo trong vòng lặp trống, nhưng echo vòng lặp kết thúc thì không.

Khi tôi chạy lần thứ hai, nó đã được đặt và xuất ra giá trị của nó, bỏ qua bộ cho đến khi vòng lặp đóng.

Ý tưởng tại sao đây là vấn đề và giải pháp thay thế là gì?

Trả lời

9

Đó là vì khối() được phân tích cú pháp chỉ một lần, nó thay thế% TMPFILE% trước khi nó chạy vòng lặp của bạn.

+1

Cảm ơn, tôi vừa nhìn thấy KHỞI ĐỘNG ENABLEDELAYED mở rộng tập trung – theschmitzer

21

Đối với hồ sơ, kịch bản sửa lại trông như thế này:

setlocal ENABLEDELAYEDEXPANSION 

for %%f in (%MYTARGETDIR%\*config.xml) do (

    SET TMPFILE=%%F.tmp 

    echo In loop !TMPFILE! 
) 

echo End loop %TMPFILE% 

Cảm ơn chris giúp đỡ của bạn.

16

Vì biến môi trường được thay thế khi lệnh là đọc. Đối với lệnh sau:

for %%f in (%mytargetdir%\*config.xml) do (
    set tmpfile=%%f.tmp 
    echo In loop %tmpfile% 
) 

toàn bộ lệnh (từ for đến dấu ngoặc đơn) được đọc và thay thế trước khi thực thi.

Bạn cần phải sử dụng mở rộng chậm, chẳng hạn như với:

@echo off 
    setlocal enableextensions enabledelayedexpansion 
    set full=/u01/users/pax 
:loop1 
    if not "!full:~-1!" == "/" (
     set full2=!full:~-1!!full2! 
     set full=!full:~,-1! 
     goto :loop1 
    ) 
    echo !full! 
    endlocal 

Khi bạn kích hoạt trì hoãn mở rộng, các "%" mốc vẫn hoạt động như trước nhưng bạn có thể sử dụng "!" đánh dấu để làm việc mở rộng bị trì hoãn.

+2

Ví dụ của bạn có thể có một chút đơn giản hơn tho :) – Lajcik

6

Bạn cũng có thể sử dụng CALL SET thay vì mở rộng chậm trễ.

+0

Cách dễ đọc hơn! –

2

Thông thường, tôi gọi CMD.EXE bằng các công tắc/e: on và/v: on để bật tiện ích mở rộng lệnh và mở rộng biến trễ. Sau đó, bất kỳ tập lệnh batch nào mà tôi sử dụng đều được mã hóa để kiểm tra xem việc mở rộng biến trễ có được bật hay không.

Đây là lần đầu tiên tôi nghe nói về các đối số SETLOCAL. Tôi đã kiểm tra với SETLOCAL /? và chắc chắn đủ! Đây là một thời gian và tiết kiệm mã cho tôi.

Tuy nhiên, tôi đã nhận thấy rằng tiện ích mở rộng lệnh phải được bật trong CMD.EXE trước khi SETLOCAL nhận ra tùy chọn ENABLEDELAYEDEXPANSION. Đây là từ đầu ra của SETLOCAL /?

If Command Extensions are enabled SETLOCAL changes as follows: 

SETLOCAL batch command now accepts optional arguments: 
     ENABLEEXTENSIONS/DISABLEEXTENSIONS 
      enable or disable command processor extensions. These 
      arguments takes precedence over the CMD /E:ON or /E:OFF 
      switches. See CMD /? for details. 
     ENABLEDELAYEDEXPANSION/DISABLEDELAYEDEXPANSION 
      enable or disable delayed environment variable 
      expansion. These arguments takes precedence over the CMD 
      /V:ON or /V:OFF switches. See CMD /? for details. 

Cảm ơn cả hai vì câu trả lời có giá trị này.

Các vấn đề liên quan