Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the error message appear when `IF` comparison is in the piped block command?

I simplified the code. The following three are work.

for /L %a in (1,1,9) do @(if %a NEQ 0 (echo %a))

&

for /L %a in (1,1,9) do @(if not %a == 0 (echo %a))

&

(for /L %a in (1,1,9) do @(if not %a == 0 (echo %a)))|sort /R

But the next one didn't work,

(for /L %a in (1,1,9) do @(if %a NEQ 0 (echo %a)))|sort /R

What's the problem of NEQ in the piped block command?

more simplified,

This works, (if 3 == 3 echo yes)|sort

This doesn't work, (if 3 NEQ 2 echo yes)|sort

Part of my code.

@echo off
setlocal enabledelayedexpansion
set Unx_path=.....\bin\UnxUtils\
(
for /F %%a in ('^""%Unx_path%pclip.exe"^|"%Unx_path%sed.exe" -r "s/^^$/none/"^|"%Unx_path%sed.exe" -rf "script_file"^"') do @(
  if not "%%a" == "none" (
    "%Unx_path%grep.exe" -iEe "%%a" "file4search"|"%Unx_path%sed.exe" -r "s/^^[^,]+$/,&/";"s/^^([^.]+)[.][^.]+$/\1/"|"%Unx_path%gawk.exe" "BEGIN{FS=\",\";ORS=\" \"}{print $2}"|"%Unx_path%sed.exe" "s/%%a//I g";"s/.*/%%a &|/";"s/ -/ /g";"s/ |/\n/g";"s/ /\t/g";"s/~/\t/g"
  ) else (
    echo none
  )
)
)|"%Unx_path%gclip.exe"
exit /b
like image 637
enjoying Avatar asked Dec 18 '22 17:12

enjoying


2 Answers

try this:

set "myline=if 3 NEQ 2 echo yes"

( %myLin^e%)|sort

or from batch file (double expansion works differently from batch file and the console):

set "myline=if 3 NEQ 2 echo yes"

( %%myLine%%)|sort

The "mystery" was solved by jeb here and here . Though you are facing the issue before the pipe it is the same bug because the cmd creates two threads on each side of the pipe.

Here's how the for loop can be made to work:

set "line=if %a NEQ 0"
(for /L %a in (1,1,9) do @( %lin^e% echo %a))|sort /R
like image 138
npocmaka Avatar answered Jan 05 '23 16:01

npocmaka


For testing purposes the cmdcmdline variable can be used.
But this fails, when somewhere in the expression is a syntax error, as the complete code block will be dropped.

@echo off
echo dummy | (
echo %%cmdcmdline%
if 1 NEQ 2 echo Work
)

This results into "2" can't be syntactically evaluated here (From german "2" kann syntaktisch an dieser Stelle nicht verarbeitet werden.)

So exactly in the case of a syntax error, you can't see the cause!

I build a small debug variable for this case

@echo off
setlocal
(set \n=^
%=empty=%
)
set "debug=echo ### %%cmdcmdline%% ^) %%\n%%"
echo dummy | (
    %debug%
    if 1 NEQ 2 echo Work
)

When you add the %debug% you will see the cmdcmdline, but the code will not be executed, so you can examine how different modification take effect.

Like

...
| ( 
  %debug%
  break & if 1 NEQ 2 echo THIS FAILS
)

but

...
| ( 
  %debug%
  break ^& if 1 NEQ 2 echo This Works !!!
)

The trick is to add ^) %%\n%%, this closes the debug expression code block with ) and cancels further parsing of the remaing code by the linefeed %%\n%%.

like image 35
jeb Avatar answered Jan 05 '23 17:01

jeb