Có những phương pháp tránh ^
trình tự thoát.
Bạn có thể sử dụng các biến có mở rộng bị trì hoãn. Dưới đây là một trình diễn kịch bản hàng loạt nhỏ
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!
Hoặc bạn có thể sử dụng vòng lặp FOR / F. Từ dòng lệnh:
for /f "delims=" %A in ("<html>") do @echo %~A
Hoặc từ một tập lệnh hàng loạt:
@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A
Lý do những phương pháp làm việc là vì cả hai mở rộng chậm và CHO mở rộng biến xảy ra sau khi các nhà khai thác đặc biệt thích <
, >
, &
, |
, &&
, ||
được phân tích cú pháp. Hãy xem Trình thông dịch lệnh Windows (CMD.EXE) phân tích cú pháp tập lệnh như thế nào? để biết thêm thông tin.
sin3.14 chỉ ra rằng các đường ống có thể yêu cầu nhiều lần thoát . Ví dụ:
echo ^^^<html^^^>|findstr .
Lý do các đường ống yêu cầu nhiều lần thoát là vì mỗi bên của đường ống được thực thi trong một quy trình CMD mới, do đó đường được phân tích cú pháp nhiều lần. Hãy xem Tại sao việc mở rộng bị trì hoãn không thành công khi bên trong một khối mã có đường ống?để giải thích về nhiều hậu quả khó xử của việc triển khai đường ống của Window.
Có một phương pháp khác để tránh thoát nhiều lần khi sử dụng đường ống. Bạn có thể khởi tạo rõ ràng quy trình CMD của riêng mình và bảo vệ lối thoát duy nhất bằng dấu ngoặc kép:
cmd /c "echo ^<html^>"|findstr .
Nếu bạn muốn sử dụng kỹ thuật mở rộng trì hoãn để tránh thoát, thì còn có nhiều điều bất ngờ hơn nữa (Bạn có thể không ngạc nhiên nếu bạn là chuyên gia về thiết kế CMD.EXE, nhưng không có tài liệu chính thức của MicroSoft giải thích về điều này)
Hãy nhớ rằng mỗi bên của đường ống được thực thi trong quy trình CMD.EXE của riêng nó, nhưng quy trình này không kế thừa trạng thái mở rộng bị trì hoãn - nó được mặc định là TẮT. Vì vậy, bạn phải khởi tạo rõ ràng quy trình CMD.EXE của riêng mình và sử dụng tùy chọn / V: ON để kích hoạt tính năng mở rộng bị trì hoãn.
@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .
Lưu ý rằng mở rộng bị trì hoãn đang TẮT trong tập lệnh lô chính.
Nhưng tất cả sẽ tan vỡ nếu mở rộng bị trì hoãn được bật trong tập lệnh mẹ. Cách sau không hoạt động:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .
Vấn đề là nó !test!
được mở rộng trong tập lệnh mẹ, vì vậy quy trình CMD mới đang cố gắng phân tích cú pháp không được bảo vệ <
và >
.
Bạn có thể thoát khỏi !
, nhưng điều đó có thể trở nên khó khăn, bởi vì nó phụ thuộc vào việc có !
được trích dẫn hay không.
Nếu không được trích dẫn, thì bắt buộc phải thoát kép:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .
Nếu được trích dẫn, thì một lối thoát duy nhất được sử dụng:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .
Nhưng có một thủ thuật đáng ngạc nhiên giúp tránh tất cả các lần thoát - bao quanh bên trái của đường ống ngăn không cho tập lệnh mẹ mở rộng !test!
quá sớm:
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .
Nhưng tôi cho rằng ngay cả khi đó không phải là bữa trưa miễn phí, bởi vì trình phân tích cú pháp hàng loạt giới thiệu một khoảng trống thừa (có lẽ không mong muốn) ở cuối khi dấu ngoặc đơn được sử dụng.
Aint batch scripting fun ;-)