Lô tương đương với Bash backticks


97

Khi làm việc với Bash, tôi có thể đặt đầu ra của một lệnh vào lệnh khác như sau:

my_command `echo Test`

sẽ giống như

my_command Test

(Rõ ràng, đây chỉ là một ví dụ không thực tế.)

Tôi chỉ tự hỏi liệu bạn có thể làm điều tương tự trong Batch không.


Câu trả lời:


53

Bạn có thể làm điều đó bằng cách chuyển hướng đầu ra đến một tệp trước. Ví dụ:

echo zz > bla.txt
set /p VV=<bla.txt
echo %VV%

16
Nó yêu cầu bạn tìm một nơi mà bạn có quyền ghi để lưu trữ tệp tạm thời; bạn phải dọn dẹp sau khi chính mình; ví dụ này chỉ cho phép bạn đọc dòng đầu tiên của đầu vào. Đối với tất cả các mục đích thực tế, for /fbiến thể là một biến thể tốt hơn nhiều.
Joey

@grawity - cùng với%random%
bacar

1
@joey Nó có đọc từng dòng, nhưng làm thế nào để nối với một đối số dòng lệnh trong một lệnh duy nhất .
user877329

nó xử lý (các) dòng mới như thế nào?
andrewrk

103

Bạn có thể nhận được một chức năng tương tự bằng cách sử dụng tập lệnh cmd.exe với for /flệnh:

for /f "usebackq tokens=*" %%a in (`echo Test`) do my_command %%a

Vâng, nó hơi không rõ ràng (ít nhất để nói rằng), nhưng đó là những gì ở đó.

Xem for /?các chi tiết đẫm máu.

Chú thích bên: Tôi nghĩ rằng để sử dụng " echo" bên trong các dấu gạch ngược trong một for /flệnh "" sẽ cần phải được thực hiện bằng cách sử dụng " cmd.exe /c echo Test" vì echolà một lệnh nội bộ cmd.exe, nhưng nó hoạt động theo cách tự nhiên hơn. Các tập lệnh hàng loạt của Windows luôn làm tôi ngạc nhiên bằng cách nào đó (nhưng thường không phải theo cách tốt).


2
Bạn thường phải làm điều này khi thực thi nội trang vỏ từ các chương trình bên ngoài không tự động tạo ra một trình bao. Tức là C system()là tốt, iirc, vì nó bắt đầu một trình bao trong mọi trường hợp nhưng .NET Process.Startcần phải gọi trình bao một cách rõ ràng. Một cái gì đó như thế, iirc. Trong mọi trường hợp, tôi coi đây là câu trả lời tốt hơn câu trả lời được chấp nhận :-)
Joey

2
Các tùy chọn để forkhông làm tổn thương nhưng nhầm lẫn vấn đề. Còn điều này:for /f %%a in ('"echo Test"') do my_command %%a
Evan Haas

9
Sử dụng một% duy nhất thay vì %% khi thực thi cùng một dòng lệnh, thay vì trong một tập lệnh lô.
jsears

2
Dường như không hoạt động tốt với đường ống, ví dụ: toán tử ">". Nhưng nếu không thì điều này thật tuyệt vời. Trừ khi đây chỉ là vấn đề% so với %% mà tôi gặp phải.
Jonathan

3
@Evan: tokens=*là quan trọng. Ngược lại, nếu kết quả của lệnh bao gồm khoảng trắng, thì chỉ có từ đầu tiên được xuất. Khởi này tại dấu nhắc: for /f %a in ('"echo foo bar"') do echo "%a". Nó sẽ in "foo".
Dan Dascalescu,

29

Đọc tài liệu về lệnh "for": for /?

Đáng buồn là tôi không đăng nhập vào Windows để tự kiểm tra, nhưng tôi nghĩ những thứ như thế này có thể gần đúng với những gì bạn muốn:

for /F %i in ('echo Test') do my_command %i

6
Trong trường hợp người khác tình cờ gặp phải điều này, khi lệnh được thực thi từ tệp batch (* .bat), cả hai biến% i cần phải là dấu phần trăm kép: %% i.
mgouin

3

Bạn luôn có thể chạy Bash bên trong Windows. Tôi làm điều đó mọi lúc với MSYS (hiệu quả hơn nhiều so với Cygwin ).


Thật không may MSYS là hầu như không duy trì bây giờ, để có được một bash up-to-date bạn cần phải cài đặt nó một cách riêng biệt
Ed Randall

1
BusyBox thậm chí còn nhỏ hơn (~ 432KB). Tuy nhiên, không phải là một Bash đầy đủ, chỉ là Ash. Nhận cổng Windows không chính thức tại đây: frippery.org/busybox
Martin

3

Có thể tôi đang hiểu sai cú pháp của for /fphương thức chuẩn , nhưng khi tôi đặt một lệnh rất phức tạp liên quan đến && và | trong backticks trong giới hạn của for /f, nó gây ra vấn đề. Có thể sửa đổi một chút so với thông thường để xử lý một lệnh phức tạp tùy ý:

SET VV=some_command -many -arguments && another_command -requiring -the-other -command | handling_of_output | more_handling
for /f "usebackq tokens=*" %%a in (`%VV%`) do mycommand %%a

Bằng cách đặt lệnh đầy đủ và phức tạp của bạn vào một biến trước, sau đó đặt tham chiếu đến biến trong giới hạn thay vì đặt lệnh phức tạp trực tiếp vào giới hạn của vòng lặp for, bạn có thể tránh được các vấn đề về diễn giải cú pháp. Hiện tại, nếu tôi sao chép chính xác lệnh mà tôi đã đặt cho VVbiến trong ví dụ trên vào nơi nó được sử dụng, %VV%thì nó sẽ gây ra lỗi cú pháp.


1
Điều này không hiệu quả với tôi, nhưng tôi thấy rằng bạn có thể thực hiện việc tạo đường ống trực tiếp trong lệnh for nếu bạn thoát nó bằng carat (^): for / f "usebackq tokens = *" %% a in (`command ^ | command`) do command %% a
Heptite

@Heptite Thẻ thoát không hoạt động với tôi, nhưng dòng lệnh xung quanh với dấu ngoặc kép thì có.
Alexandr Zarubkin

@Heptite Trong trường hợp của tôi, tôi không biết trước chuỗi lệnh mà mình sẽ cần chạy, chúng được trích xuất ra khỏi một tệp trong một trường hợp và được chuyển vào trong một trường hợp khác. Với việc thoát lệnh, bạn cần biết số lần thoát lệnh dựa trên số lượng trình thông dịch mà nó sẽ chạy qua và trong các trường hợp sử dụng của tôi, đó không phải là số lượng trình thông dịch nhất quán.
mtalexan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.