Передайте пакетный сценарий Windows с проверкой существования переменной другой команде

Я пытаюсь заставить работать следующий код, который проверяет наличие переменной в канале, что является упрощением реального кода, который я хочу выполнить, который содержит другой код внутри блока скрипта, но это демонстрирует проблему:

( if defined some_variable echo ok ) | more
echo was unexpected at this time

Это дает мне эхо сообщения, которое было неожиданным в это время. Цитата с круглыми скобками после оператора if не решает проблему, она просто жалуется на круглые скобки

( if defined some_variable ( echo ok ) ) | more
( was unexpected at this time.

Оба варианта оператора if будут работать, если они не находятся в передаваемом блоке кода.

if defined some_variable echo ok
ok
if defined some_variable ( echo ok )
ok

Кроме того, я могу выполнить блок кода, но вывести его в файл, и это работает для захвата вывода блока сценария, особенно даже с несколькими строками кода в блоке сценария:

( if ok defined some_variable echo ok ) > some_text_file.txt

Этот стиль if работает внутри структуры script-block-to-pipe:

( if 1==1 echo ok ) | more
ok
( if NOT 1==2 echo ok ) | more
ok

Но я не понимаю, почему проверка существования с ключевым словом «определенное» полностью разрушает эту структуру трубопровода.

Моя конечная цель — заставить следующий код работать в пакетном сценарии (в котором больше возможностей, чем в приведенном ниже примере), но проблема сводится к упрощению, упомянутому в начале, что бомбы. Приведенный ниже код будет работать как пакетный скрипт для вывода вывода в командную строку и файл журнала, но проверки переменных в блоке скрипта уничтожат его.

( 
  echo some_stuff_like_a_program_header
  
  #test existence of a variable and if not defined earlier in script then echo some stuff
  if NOT defined some_variable then_alert_user_with_error_msg
  
  if some_variable==some_value (do_some_stuff) else (do_other_stuff)
  
) | powershell.exe -command '& { $input | tee-object -file out.log }'

person Russ Thils    schedule 01.04.2021    source источник


Ответы (1)


Это ошибка парсера, оператор if будет сжат до if definedsome_variable echo ok.
Вы видите, что пробел между defined и some_variable удален.

Вы можете решить эту проблему, используя позднее расширение переменной.

set "myLine=if defined path echo ok"
echo pipe | ( %%myLine%%)

Или с экранированными пробелами (из @enjoying SO:Почему появляется сообщение об ошибке, когда сравнение IF находится в команде блока конвейера? )

echo pipe | ( if defined ^  path echo ok )

Чтобы увидеть, что происходит внутри, вы можете попробовать эту отладочную конструкцию.

@echo off
setlocal
(set \n=^
%=empty=%
)
set "debug=echo ### %%cmdcmdline%% ^) %%\n%%"
echo dummy | (
    %debug%
    if defined some_variable echo ok
)
person jeb    schedule 01.04.2021