第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么延遲擴展失敗時,在管道內(nèi)的代碼塊?

為什么延遲擴展失敗時,在管道內(nèi)的代碼塊?

為什么延遲擴展失敗時,在管道內(nèi)的代碼塊?下面是一個簡單的批處理文件,它演示了如果延遲擴展是在被管道傳輸?shù)膲K內(nèi),那么延遲擴展是如何失敗的。(失敗在腳本的末尾)有人能解釋為什么會這樣嗎?我有一個工作,但它需要創(chuàng)建一個臨時文件。我最初是在工作時遇到這個問題的。在Windows批處理文件中查找文件并按大小排序@echo off setlocal enableDelayedExpansion set test1=x set test2=y set test3=z echo( echo NORMAL EXPANSION TEST echo Unsorted works (   echo %test3%   echo %test1%   echo %test2% ) echo( echo Sorted works (   echo %test3%   echo %test1%   echo %test2% ) | sort echo( echo --------- echo( echo DELAYED EXPANSION TEST echo Unsorted works (   echo !test3!   echo !test1!   echo !test2! ) echo( echo Sorted fails (   echo !test3!   echo !test1!   echo !test2! ) | sort echo( echo Sort workaround (   echo !test3!   echo !test1!   echo !test2! )>temp.txt sort temp.txt del temp.txt以下是結果NORMAL EXPANSION TEST Unsorted works z x y Sorted works x y z --------- DELAYED EXPANSION TEST Unsorted works z x y Sorted fails !test1! !test2! !test3! Sort workaround x y z
查看完整描述

3 回答

?
當年話下

TA貢獻1890條經(jīng)驗 獲得超9個贊

正如Aacini所顯示的,似乎許多事情都是在管道中失敗的。

echo hello | set /p var=
echo here | call :function

但在現(xiàn)實中,理解管道的工作原理只是一個問題。

管道的每一端都在自己的刻板時間線程中啟動自己的cmd.exe。
這就是為什么如此多的東西似乎被打破的原因。

但是有了這些知識,你就可以避免這種情況,創(chuàng)造新的效果。

echo one | ( set /p varX= & set varX )
set var1=var2
set var2=content of two
echo one | ( echo %%%var1%%% )
echo three | echo MYCMDLINE %%cmdcmdline%%
echo four  | (cmd /v:on /c  echo 4: !var2!)

編輯:深度分析

如Dbenham所示,管道的兩側對于膨脹階段都是等效的。
主要規(guī)則似乎是:

正常的批處理解析器階段已經(jīng)完成。
.。百分比膨脹
.。特殊字符相位/塊開始檢測
.。延遲擴展(但只在啟用延遲擴展且不是命令塊的情況下)

啟動cmd.exeC:\Windows\system32\cmd.exe  /S /D /c"<BATCH COMMAND>"
這些擴展遵循cmd行解析器的規(guī)則,而不是批處理行解析器的規(guī)則。

.。百分比膨脹
.。延遲擴展(但前提是啟用延遲擴展)

這個<BATCH COMMAND>如果它在圓括號塊內(nèi),將被修改。

(
echo one %%cmdcmdline%%
echo two
) | more

被稱為C:\Windows\system32\cmd.exe  /S /D /c" ( echo one %cmdcmdline% & echo two )",所有新行都更改為&接線員。

為什么延遲的擴張階段會受到括號的影響?
我想,它不能在批處理解析器階段展開,因為塊可以由許多命令組成,延遲擴展在執(zhí)行一行時生效。

(
set var=one
echo !var!
set var=two
) | more

顯然!var!不能在批處理上下文中計算,因為這些行僅在cmd行上下文中執(zhí)行。

但是為什么在這種情況下可以在批處理上下文中評估它呢?

echo !var! | more

在我看來,這是一種“錯誤”或不和諧的行為,但這不是第一次

編輯:添加LF技巧

正如dbenham所顯示的,cmd行為似乎存在一些限制,即將所有行提要更改為&.

(
  echo 7: part1
  rem This kills the entire block because the closing ) is remarked!
  echo part2
) | more

這導致
C:\Windows\system32\cmd.exe  /S /D /c" ( echo 7: part1 & rem This ...& echo part2 ) "
這個rem會注意到整條線尾,所以連最后的括號也沒有了。

但是,您可以通過嵌入您自己的行提要來解決這個問題!

set LF=^


REM The two empty lines above are required
(
  echo 8: part1
  rem This works as it splits the commands %%LF%% echo part2  
) | more

這導致C:\Windows\system32\cmd.exe  /S /D /c" ( echo 8: part1 %cmdcmdline% & rem This works as it splits the commands %LF% echo part2  )"

當解析器在解析括號時展開%lf%時,生成的代碼如下所示

( echo 8: part1 & rem This works as it splits the commands 
  echo part2  )

這,這個%LF%行為總是在括號內(nèi)工作,在批處理文件中也是如此。
但不是在“正?!本€上,有一個<linefeed>將停止對這一行的解析。

編輯:異步不是全部事實

我說過這兩個線程都是異步的,通常是這樣的。
但實際上,當右線程沒有使用管道數(shù)據(jù)時,左線程可以鎖定自己。
“管道”緩沖區(qū)中似乎有1000個字符的限制,然后線程被阻塞,直到數(shù)據(jù)被消耗為止。

@echo off
(
    (
    for /L %%a in ( 1,1,60 ) DO (
            echo A long text can lock this thread
            echo Thread1 ##### %%a > con
        )
    )
    echo Thread1 ##### end > con
) | (
    for /L %%n in ( 1,1,6) DO @(
        ping -n 2 localhost > nul
        echo Thread2 ..... %%n
        set /p x=
    )
)


查看完整回答
反對 回復 2019-06-29
?
Smart貓小萌

TA貢獻1911條經(jīng)驗 獲得超7個贊

我不確定我是應該編輯我的問題,還是把它作為答案發(fā)布。

我已經(jīng)模糊地知道,管道在自己的cmd.exe“會話”中同時執(zhí)行左側和右側。但是Aacini和Jeb的回答迫使我認真思考和調(diào)查管道的情況。(感謝Jeb演示了當管道進入SET/P時發(fā)生了什么!)

我開發(fā)了這個調(diào)查腳本-它幫助解釋了很多,但也演示了一些奇怪和意外的行為。我將發(fā)布腳本,然后是輸出。最后,我將提供一些分析。

@echo off
cls
setlocal disableDelayedExpansion
set var1=value1
set "var2="
setlocal enableDelayedExpansion

echo on
@echo NO PIPE - delayed expansion is ON
echo 1: %var1%, %var2%, !var1!, !var2!
(echo 2: %var1%, %var2%, !var1!, !var2!)

@echo(
@echo PIPE LEFT SIDE - Delayed expansion is ON
echo 1L: %%var1%%, %%var2%%, !var1!, !var2! | more
(echo 2L: %%var1%%, %%var2%%, !var1!, !var2!) | more
(setlocal enableDelayedExpansion & echo 3L: %%var1%%, %%var2%%, !var1!, !var2!) | more
(cmd /v:on /c echo 4L: %%var1%%, %%var2%%, !var1!, !var2!) | more
cmd /v:on /c echo 5L: %%var1%%, %%var2%%, !var1!, !var2! | more
@endlocal
@echo(
@echo Delayed expansion is now OFF
(cmd /v:on /c echo 6L: %%var1%%, %%var2%%, !var1!, !var2!) | more
cmd /v:on /c echo 7L: %%var1%%, %%var2%%, !var1!, !var2! | more

@setlocal enableDelayedExpansion
@echo(
@echo PIPE RIGHT SIDE - delayed expansion is ON
echo junk | echo 1R: %%var1%%, %%var2%%, !var1!, !var2!
echo junk | (echo 2R: %%var1%%, %%var2%%, !var1!, !var2!)
echo junk | (setlocal enableDelayedExpansion & echo 3R: %%var1%%, %%var2%%, !var1!, !var2!)
echo junk | (cmd /v:on /c echo 4R: %%var1%%, %%var2%%, !var1!, !var2!)
echo junk | cmd /v:on /c echo 5R: %%var1%%, %%var2%%, !var1!, !var2!
@endlocal
@echo(
@echo Delayed expansion is now OFF
echo junk | (cmd /v:on /c echo 6R: %%var1%%, %%var2%%, !var1!, !var2!)
echo junk | cmd /v:on /c echo 7R: %%var1%%, %%var2%%, !var1!, !var2!


這是輸出

NO PIPE - delayed expansion is ON

C:\test>echo 1: value1, , !var1!, !var2!
1: value1, , value1,

C:\test>(echo 2: value1, , !var1!, !var2! )
2: value1, , value1,

PIPE LEFT SIDE - Delayed expansion is ON

C:\test>echo 1L: %var1%, %var2%, !var1!, !var2!   | more
1L: value1, %var2%, value1,


C:\test>(echo 2L: %var1%, %var2%, !var1!, !var2! )  | more
2L: value1, %var2%, !var1!, !var2!


C:\test>(setlocal enableDelayedExpansion   & echo 3L: %var1%, %var2%, !var1!, !var2! )  | more
3L: value1, %var2%, !var1!, !var2!


C:\test>(cmd /v:on /c echo 4L: %var1%, %var2%, !var1!, !var2! )  | more
4L: value1, %var2%, value1, !var2!


C:\test>cmd /v:on /c echo 5L: %var1%, %var2%, !var1!, !var2!   | more
5L: value1, %var2%, value1,


Delayed expansion is now OFF

C:\test>(cmd /v:on /c echo 6L: %var1%, %var2%, !var1!, !var2! )  | more
6L: value1, %var2%, value1, !var2!


C:\test>cmd /v:on /c echo 7L: %var1%, %var2%, !var1!, !var2!   | more
7L: value1, %var2%, value1, !var2!


PIPE RIGHT SIDE - delayed expansion is ON

C:\test>echo junk   | echo 1R: %var1%, %var2%, !var1!, !var2!
1R: value1, %var2%, value1,

C:\test>echo junk   | (echo 2R: %var1%, %var2%, !var1!, !var2! )
2R: value1, %var2%, !var1!, !var2!

C:\test>echo junk   | (setlocal enableDelayedExpansion   & echo 3R: %var1%, %var2%, !var1!, !var2! )
3R: value1, %var2%, !var1!, !var2!

C:\test>echo junk   | (cmd /v:on /c echo 4R: %var1%, %var2%, !var1!, !var2! )
4R: value1, %var2%, value1, !var2!

C:\test>echo junk   | cmd /v:on /c echo 5R: %var1%, %var2%, !var1!, !var2!
5R: value1, %var2%, value1,

Delayed expansion is now OFF

C:\test>echo junk   | (cmd /v:on /c echo 6R: %var1%, %var2%, !var1!, !var2! )
6R: value1, %var2%, value1, !var2!

C:\test>echo junk   | cmd /v:on /c echo 7R: %var1%, %var2%, !var1!, !var2!
7R: value1, %var2%, value1, !var2!

我測試了管道的左側和右側,以證明處理是對稱的。

測試1和2表明,在正常批處理情況下,括號對延遲擴展沒有任何影響。

測試1L,1R:延遲擴張如預期一樣有效。Var2是未定義的,所以%var2%和!var2!輸出顯示這些命令是在命令行上下文中執(zhí)行的,而不是在批處理上下文中執(zhí)行的。換句話說,使用命令行解析規(guī)則代替批處理解析。(見Windows命令解釋器(cmd.exe)如何解析腳本?編輯-!VAR 2!在父批處理上下文中展開。

測試2L,2R:括號禁用延遲擴展!我心里很奇怪也很意外。編輯-Jeb認為這是一個MS錯誤或設計缺陷。我同意,不一致的行為似乎沒有任何合理的理由

測試3L,3R: setlocal EnableDelayedExpansion不起作用。但這是預期的,因為我們處于命令行上下文中。setlocal只在批處理上下文中工作。

測試4L,4R:延遲擴展最初啟用,但括號禁用它。CMD /V:ON重新啟用延遲擴展,一切都按預期進行。我們?nèi)匀挥忻钚猩舷挛?,輸出和預期的一樣。

測試5L,5R:幾乎與4L一樣,除了延遲擴展之外,在以下情況下已啟用了4R:CMD /V:on被處決了。%var2%提供預期的命令行上下文輸出。但是!變了!輸出為空白,這在批處理上下文中是預期的。這是另一個非常奇怪和意外的行為。編輯-實際上這是有意義的,現(xiàn)在我知道了!變種2!在父批處理上下文中展開。

測試6L,6R,7L,7R:這些類似于測試4L/R,5L/R,除了現(xiàn)在延遲擴展開始禁用。這一次,所有4種場景都給出了預期的!var2!批處理上下文輸出。

如果有人能為2L,2R和5L,5R的結果提供一個合乎邏輯的解釋,那么我將選擇它作為我最初問題的答案。否則,我可能會接受這個帖子作為答案(實際上更多的是觀察發(fā)生了什么,而不是回答)。刺死它了!


增編:作為對Jeb的評論的回應,這里有更多的證據(jù)表明,在命令行上下文中,而不是在批處理上下文中,命令在批處理中執(zhí)行。

這個批處理腳本:

@echo on
call echo batch context %%%%
call echo cmd line context %%%% | more

給出這個輸出:

C:\test>call echo batch context %%
batch context %

C:\test>call echo cmd line context %%   | more
cmd line context %%



最后增編

我增加了一些額外的測試和結果,以證明到目前為止的所有發(fā)現(xiàn)。我還演示了可變膨脹發(fā)生在管道處理之前。最后,我展示了管道處理的一些有趣的副作用,當多行塊被折疊成一行時。

@echo off
cls
setlocal disableDelayedExpansion
set var1=value1
set "var2="
setlocal enableDelayedExpansion

echo on
@echo(
@echo Delayed expansion is ON
echo 1: %%, %%var1%%, %%var2%%, !var1!, ^^^!var1^^^!, !var2!, ^^^!var2^^^!, %%cmdcmdline%% | more
(echo 2: %%, %%var1%%, %%var2%%, !var1!, ^^^!var1^^^! !var2!, %%cmdcmdline%%) | more
for %%a in (Z) do (echo 3: %%a %%, %%var1%%, %%var2%%, !var1!, ^^^!var1^^^! !var2!, %%cmdcmdline%%) | more
(
  echo 4: part1
  set "var2=var2Value
  set var2
  echo "
  set var2
)
(
  echo 5: part1
  set "var2=var2Value
  set var2
  echo "
  set var2
  echo --- begin cmdcmdline ---
  echo %%cmdcmdline%%
  echo --- end cmdcmdline ---
) | more
(
  echo 6: part1
  rem Only this line remarked
  echo part2
)
(
  echo 7: part1
  rem This kills the entire block because the closing ) is remarked!
  echo part2
) | more

這是輸出

Delayed expansion is ON

C:\test>echo 1: %, %var1%, %var2%, !var1!, ^!var1^!, !var2!, ^!var2^!, %cmdcmdline%   | more
1: %, value1, %var2%, value1, !var1!, , !var2!, C:\Windows\system32\cmd.exe  /S /D /c" echo 1: %, %var1%, %var2%, value1, !var1!, , !var2!, %cmdcmdline% "


C:\test>(echo 2: %, %var1%, %var2%, !var1!, ^!var1^! !var2!, %cmdcmdline% )  | more
2: %, value1, %var2%, !var1!, !var1! !var2!, C:\Windows\system32\cmd.exe  /S /D /c" ( echo 2: %, %var1%, %var2%, !var1!, ^!var1^! !var2!, %cmdcmdline% )"


C:\test>for %a in (Z) do (echo 3: %a %, %var1%, %var2%, !var1!, ^!var1^! !var2!, %cmdcmdline% )  | more

C:\test>(echo 3: Z %, %var1%, %var2%, !var1!, ^!var1^! !var2!, %cmdcmdline% )  | more
3: Z %, value1, %var2%, !var1!, !var1! !var2!, C:\Windows\system32\cmd.exe  /S /D /c" ( echo 3: Z %, %var1%, %var2%, !var1!, ^!var1^! !var2!, %cmdcmdline% )"

C:\test>(
echo 4: part1
 set "var2=var2Value
 set var2
 echo "
 set var2
)
4: part1
var2=var2Value
"
var2=var2Value

C:\test>(
echo 5: part1
 set "var2=var2Value
 set var2
 echo "
 set var2
 echo --- begin cmdcmdline ---
 echo %cmdcmdline%
 echo --- end cmdcmdline ---
)  | more
5: part1
var2=var2Value & set var2 & echo
--- begin cmdcmdline ---
C:\Windows\system32\cmd.exe  /S /D /c" ( echo 5: part1 & set "var2=var2Value
var2=var2Value & set var2 & echo
" & set var2 & echo --- begin cmdcmdline --- & echo %cmdcmdline% & echo --- end cmdcmdline --- )"
--- end cmdcmdline ---


C:\test>(
echo 6: part1
 rem Only this line remarked
 echo part2
)
6: part1
part2

C:\test>(echo %cmdcmdline%   & (
echo 7: part1
 rem This kills the entire block because the closing ) is remarked!
 echo part2
) )  | more

測試1:2:總結所有的行為,%cmdcmdline%技巧確實有助于演示正在發(fā)生的事情。

測試3:演示變量展開仍然適用于管道塊。

測試4:/5:和6:/7:顯示管道與多行塊的工作方式的有趣的副作用。小心!

我必須相信,在復雜的管道場景中找出轉義序列將是一場噩夢。


查看完整回答
反對 回復 2019-06-29
  • 3 回答
  • 0 關注
  • 710 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網(wǎng)微信公眾號