2014-10-08 16 views
5

Tôi muốn đặt biến, ví dụ: %p% và sau đó sử dụng nó trong cùng một dòng trong CMD.Cách đặt biến và sau đó sử dụng biến đó trong cùng một dòng trong lời nhắc lệnh

ví dụ .:

set p=notepad.exe&%p% 

không này hoạt động. Nhưng %p% được đặt cho dòng tiếp theo. Do đó nếu tôi thực hiện dòng này lần thứ hai, nó hoạt động.

Tôi làm cách nào để sử dụng %p% trong cùng một dòng?

+0

Nếu mục đích của bạn là mở một số ví dụ như notepad hoặc một số tập tin, bạn có thể làm điều đó trực tiếp trong một dòng, chính xác những gì bạn muốn với biến này? – ZAT

+0

@ZAT Nó chỉ là một ví dụ. Mục đích của tôi là chuyển đổi một tập tin batch phức tạp thành một dòng duy nhất. Tất cả các mã được chuyển đổi ngoại trừ thiết lập một biến, như trên. Tôi không muốn thực thi tập tin batch trực tiếp. –

+1

Nếu bạn đang lưu trữ mã phức tạp trong các biến, thì bạn có thể quan tâm đến các macro [Hàng loạt "có đối số] (http://www.dostips.com/forum/viewtopic.php?f=3&t=1827) – dbenham

Trả lời

10

Khi bạn thực thi tệp lô, mỗi dòng hoặc khối dòng (các dòng được bao quanh trong dấu ngoặc đơn) được phân tích cú pháp đầu tiên và sau đó được thực hiện. Trong quá trình phân tích cú pháp, các hoạt động đọc trên các biến được thay thế bằng giá trị bên trong biến trước khi các lệnh được thực thi. Vì vậy, nếu trong một dòng/khối một giá trị biến được thay đổi, bạn không thể lấy giá trị thay đổi này khi trình phân tích cú pháp đã loại bỏ hoạt động đọc với giá trị trong biến trước khi thay đổi được thực hiện.

Vì vậy, mã của bạn

set p=notepad.exe&%p% 

được phân tách và chuyển đổi sang

set p=notepad.exe& 

nơi hoạt động đọc để có được %p% đã được thay thế bằng giá trị trong biến (mẫu giả định biến là trống). Sau đó, dòng phân tích cú pháp này được thực hiện.

Tại sao lại hoạt động lần thứ hai? Bởi vì trong lần chạy trước, biến đã được đặt và, nếu nó chưa được đặt lại, khi trình phân tích cú pháp thực hiện thay thế trong lần chạy thứ hai biến chứa giá trị để thay thế trong dòng.

Để thấy rằng đây là một phân tích trước khi thực hiện hành vi, bạn có thể thay đổi dòng của bạn để

set p=notepad.exe&set p 

nghĩa là, thiết lập biến và đổ nội dung môi trường (biến bắt đầu với p) và bạn sẽ thấy rằng biến đã được đặt thành notepad.exe. Vì dòng này không chứa bất kỳ thao tác đọc nào trên biến, mọi thứ hoạt động như mong đợi.

Cách giải quyết sự cố của bạn?Có một số tùy chọn

Chậm mở rộng

Khi mở rộng chậm được kích hoạt, cú pháp trên biến nội dung đã có thể được thay đổi, khi cần thiết, %var%-!var!, chỉ để phân tích cú pháp mà thay vào hoạt động đọc cần phải được trì hoãn cho đến khi thực hiện lệnh

setlocal enabledelayedexpansion 
set p=notepad.exe&!p! 

hành vi này tương tự có thể được kích hoạt nếu bộ xử lý lệnh được gọi với /v:on

cmd /v:on /c "set p=notepad.exe&!p!" 

quân một phân tích cú pháp thứ hai trên lệnh

này sử dụng lệnh call để buộc một phân tích cú pháp thứ hai trên dòng

set p=notepad.exe&call %%p%% 

Các phân tích cú pháp mặc định đầu tiên thay thế các literal %%p%% với nghĩa đen %p% (%% là dấu phần trăm thoát) mà không thực hiện bất kỳ thay thế biến nào và khi lệnh call được thực thi, dòng được phân tích cú pháp một lần nữa, vì vậy, chữ số %p% được hiểu là biến đọc và được thay thế bằng giá trị trong biến

Điều gì sẽ sử dụng? Nó phụ thuộc. Giải pháp mở rộng bị trì hoãn có thời gian thực hiện tốt hơn mà giải pháp call (call lệnh hoạt động nhiều hơn), nhưng khi mở rộng trễ được bật ký tự dấu chấm than (!) chứa trong dữ liệu trở thành vấn đề cần được xử lý đúng cách.

+3

+1 , Lưu ý rằng CALL rất chậm. Vì vậy, nếu hiệu suất là một vấn đề, thì việc mở rộng bị trì hoãn là thích hợp hơn để GỌI – dbenham

+0

@dbenham, cảm ơn bạn, bây giờ được đưa vào câu trả lời. –

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