GOOGLE ADS

вторник, 12 апреля 2022 г.

Переменные ведут себя не так, как ожидалось

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

  • Переменная iне увеличивается каждый раз, когда я это делаю.

  • Конкатенация strc, похоже, не объединяет.

  • Вот мой код:

    set i=0
    set "strc=concat:"
    for %%f in (*.mp4) do (
    set /a i+=1
    set "str=intermediate%i%.ts"
    set strc="%strc% %str%|"
    ffmpeg -i "%%f" -c copy -bsf:v h264_mp4toannexb -f mpegts "%str%"
    )
    set strc="%strc:-1%"
    ffmpeg -i "%strc%" -c copy -bsf:a aac_adtstoasc Output.mp4


    Решение проблемы

    Вы не первый, кто попал в знаменитую "ловушку отсроченного расширения" (и не последний).

    Вам нужно отложенное раскрытие, если вы хотите использовать переменную, которую вы изменили в том же блоке (блок — это последовательность команд в круглых скобках (и )).

    На отложенные переменные ссылаются !var!вместо %var%.

    Причина в том, как, cmdразбирает код. Полная строка или блок анализируются сразу, заменяя обычные переменные их значением во время анализа. Задержанные переменные оцениваются во время выполнения.

    Два простых командных файла для демонстрации:

    setlocal EnableDelayedExpansion
    set "var=hello"
    if 1==1 (
    set "var=world"
    echo %var%!var!
    )

    setlocal EnableDelayedExpansion
    for /L %%i in (1,1,5) do (
    echo %random%!random!
    )

    Примечание. Линия также рассматривается как блок:

    set "var=old"
    set "var=new" & echo %var%

    С отсроченным расширением:

    setlocal EnableDelayedExpansion
    set "var=old"
    set "var=new" & echo!var!

    Отложенное расширение по умолчанию отключено в командной строке. Если вам это действительно нужно, вы можете сделать:

    cmd /V:ON /C "set "var=hello" & echo!var!"

    Также есть способ сделать то же самое без отложенного расширения (но callстоит некоторое время, поэтому медленнее, но если по какой-то причине вы не можете/не хотите использовать отложенное расширение, это альтернатива):

    setlocal DISabledelayedexpansion
    for /L %%i in (1 1 5) do (
    call echo %random% %%random%%
    )

    Оба метода также можно использовать для отображения переменных, подобных массиву:

    (Это часто спрашивают, например, «переменная, которая содержит другую переменную» или «вложенные переменные»).

    Вот набор для использования таких массивоподобных переменных в разных ситуациях:

    С отсроченным расширением:

    setlocal ENableDelayedExpansion
    set "num=4"
    set "var[%num%]=HELLO"
    echo plain delayed:!var[%num%]!
    for /L %%i in (4 1 4) do (
    echo for delayed:!var[%%i]!
    set a=%%i
    call echo for delayed with variable: %%var[!a!]%%
    )

    без замедленного расширения:

    setlocal DISableDelayedExpansion
    set "num=4"
    set "var[%num%]=HELLO"
    call echo plain called: %%var[%num%]%%
    for /L %%i in (4 1 4) do (
    call echo FOR called: %%var[%%i]%%
    set a=%%i
    call echo FOR called with variable: %%var[%a%]%%
    )

    Примечание. setlocalНе действует вне пакетных файлов, поэтому delayedexpansionработает только:


    • В пакетных файлах

    • Когда cmd был запущен с включенным отложенным расширением ( cmd /V:ON) (по умолчанию cmd запускается с отключенным отложенным расширением )


    (Следуйте по ссылкам, если вас интересует технический фон или даже более продвинутый технический материал )

    Комментариев нет:

    Отправить комментарий

    Laravel Datatable addColumn returns ID of one record only

    Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...