2015-08-13 15 views
7

Here's one interesting thread. Và tôi đã cố gắng chơi với hai điều được thảo luận ở đó.Tại sao CALL in thông báo trợ giúp GOTO trong tập lệnh này? Và tại sao lệnh sau đó được thực hiện hai lần?

  1. Bạn có thể truy cập các nhãn có ký hiệu đặc biệt với mở rộng gấp đôi.
  2. Nhãn có chứa /? không thể sử dụng được vì GOTOCALL in thư trợ giúp của họ thay vì thực thi.

Và đây là kết quả:

@echo off 

setlocal enableDelayedExpansion 
set "label=/?" 

    call :%%label%% 
    echo == Test message to check if the CALL or GOTO (or neither) command is executed == 

exit /b 0 

:/? 
    echo == CALL or GOTO has been executed == 
exit /b 0 

Và kết quả:

Directs cmd.exe to a labeled line in a batch program. 

GOTO label 

    label Specifies a text string used in the batch program as a label. 

You type a label on a line by itself, beginning with a colon. 

If Command Extensions are enabled GOTO changes as follows: 

GOTO command now accepts a target label of :EOF which transfers control 
to the end of the current batch script file. This is an easy way to 
exit a batch script file without defining a label. Type CALL /? for a 
description of extensions to the CALL command that make this feature 
useful. 
== Test message to check if the CALL or GOTO (or neither) command is executed == 
== Test message to check if the CALL or GOTO (or neither) command is executed == 

Và mã sau CALL được thực hiện hai lần ??

EDIT

này thậm chí còn không thể giải thích với tôi:

@echo off 

setlocal enableDelayedExpansion 
set "label=/?" 
    set /a x=1 
    call :%%label%% >nul 

    set /a x=x+1 
    echo --- 
    echo -%x%- 
    echo --- 

exit /b 0 

:/? 
    echo == CALL or GOTO has been executed == 
    echo == first argument : %1 == 
exit /b 0 

Đầu ra là:

--- 
-3- 
--- 

Mã này sau khi cuộc gọi của CALL chắc chắn được thực hiện hai lần , nhưng đầu ra của lần chạy đầu tiên có thể được chuyển hướng trong cùng một dòng?

+2

Điều này làm cho điều này trở nên phức tạp hơn (nếu có thể) là nếu bạn thêm '& pause' sau khi' call' nó lặp lại mọi thứ một lần, tạm dừng và lặp lại nó ** sau ** tạm dừng! – Monacraft

Trả lời

6

Tôi luôn ngạc nhiên, rằng bạn vẫn tìm thấy những thứ chưa bao giờ đến trong tâm trí của tôi để kiểm tra.

Trái ngược với Aacini, tôi không tin rằng :/? hoạt động ở đây dưới dạng nhãn hợp lệ.
Khác điều này sẽ tìm thấy một nhãn như vậy.

Tôi giả sử rằng lệnh CALL được nội bộ bao gồm chức năng ngăn xếp chồng và sau đó chỉ cần sử dụng GOTO để chuyển đến nhãn.

Và vì bạn đang sử dụng mở rộng trễ, /? không được phát hiện bởi lệnh CALL, nhưng bằng lệnh GOTO.
goto chỉ hiển thị thông tin trợ giúp và đã hoàn tất, nhưng vì call đã đẩy tệp vào ngăn xếp, nó hoạt động như gọi filepostion này và sau đó quay trở lại cùng một vị trí!

set "help=^ /?" 
call :myLabel%%help%% 

Điều này cũng cho thấy trợ giúp, chẳng hạn như GOTO :myLabel /? sẽ thực hiện.
Nhưng lần này không

set "help=/?" 
call :myLabel %%help%% 

Tôi cho rằng, các GOTO được chỉ nhãn phân tích cú pháp bởi CALL, các thông số khác được chuyển đến %1, %2, ...

Và điều này có thể giải thích tại sao chỉ có nhãn thể sử dụng mở rộng trễ hai lần.

@echo off 
setlocal EnableDelayedExpansion 
set "label=myLabel" 
set "pointer=^!label^!" 
call :!pointer! 
exit /b 

:myLabel 
echo it works 
+1

Phải. Lệnh 'call' theo sau dấu hai chấm bắt đầu tạo ra một bối cảnh lô mới. Mã lô được tải vào ngữ cảnh này và, nếu phần tử tạo ngữ cảnh bắt đầu bằng dấu hai chấm thì nó được coi là nhãn và 'goto' được thực hiện để nhảy tới nhãn này. Nó đã được sử dụng và chỉ ra [ở đây] (http://stackoverflow.com/a/30170342/2861476). Cũng giống như một sự tò mò, có một biến nội bộ được định nghĩa chỉ để ẩn thực thi 'goto' khi' echo' được kích hoạt. –

+0

Âm thanh như câu trả lời! Điều đầu tiên xuất hiện trong tâm trí của tôi là - Có thể buộc một 'call: eof' nhảy đến cuối tập tin như' goto'.btw hầu hết các lệnh nội bộ in ra sự giúp đỡ của họ cho dù chuỗi có ở đâu không? '' được đặt trong các đối số.Nhưng chỉ 'rem' có một vấn đề với việc mở rộng gấp đôi ở đây:' set "h = /?" & call rem %% h %% ' – npocmaka

+0

@MCND - biến nội bộ nào? – npocmaka

3

Thú vị! Mã đầu tiên có thể được giảm xuống còn:

@echo off 

setlocal 
set "label=/?" 

    call :%%label%% 
    echo == Test message to check if the CALL or GOTO (or neither) command is executed == 

và vẫn hiển thị đầu ra tương tự, có nghĩa là, nó cư xử theo cùng một cách hơn so với mã này:

@echo off 

setlocal 

call :/? 
echo == Test message to check if the CALL or GOTO (or neither) command is executed == 

nơi call :/?cả một cuộc gọi lệnh nhãn hợp lệ và xem xét :/? nhãn hợp lệ. Wow!

Tại sao trợ giúp GOTO được hiển thị? Không ý kiến!!!

EDIT: kiểm tra bổ sung

Mã này:

@echo off 

setlocal 
set "label=/?" 

    set i=0 
    call :%%label%% & echo Command in same line: i=%i% 
    set /A i+=10 
    echo == Test message ==  i=%i% 

hiển thị sự giúp đỡ màn hình GOTO đầu tiên, và sau đó:

== Test message ==  i=10 
Command in same line: i=0 
== Test message ==  i=20 

nhưng nếu EnableDelayedExpansion được thêm vào và %i% được thay đổi bởi !i! trong ca ll line, sau đó nó hiển thị:

== Test message ==  i=10 
Command in same line: i=10 
== Test message ==  i=20 

là "dự kiến" ...

EDIT # 2

Các thử nghiệm dưới đây cho thấy rằng lệnh call :%%label%% KHÔNG báo cáo ERRORLEVEL = 1 tiêu chuẩn về "nhãn không tìm thấy" lỗi:

@echo off 

setlocal 
set "label=/?" 

    call :notFound 
    echo Label not found: ERRROLEVEL = %ERRORLEVEL% 
    ver > NUL 
    echo Reset errorlevel: ERRROLEVEL = %ERRORLEVEL% 

    call :%%label%% 
    echo == Test message == ERRROLEVEL = %ERRORLEVEL% 
Các vấn đề liên quan