Не удается найти указанную метку пакетного файла

Обновлено: 03.07.2024

Я написал следующий пакетный сценарий, который запускает другой пакетный сценарий в каталоге или, с добавлением флага, в дереве каталогов, а затем в эквивалентном каталоге или дереве каталогов на другом диске (Z :). Независимо от того, какой вариант я выберу, он выдает ошибку «Система не может найти указанный путь». Он делает то, что должен, если я делаю это только в одном каталоге, даже если он выдает ошибку. Он не работает успешно в дереве каталогов. Я запустил его без @echo off, чтобы попытаться понять, где он не работает, но безуспешно. Каталог, в который он пытается перейти, существует.

Вот "myotherscript" Да, чистка есть.

Любая помощь будет оценена. Благодарность

2 ответа

Я не уверен, почему этот (очень старый) вопрос был повторно активирован. Но раз уж это произошло, давайте посмотрим, сможем ли мы это закрыть.

Здесь, кажется, есть две проблемы. Первый:

выводится ошибка «Система не может найти указанный путь».

Это похоже на простую опечатку в этой строке:

Без меток «%» это попытка перейти в каталог с буквальным названием origdir , а не в исходный каталог, из которого был запущен скрипт, а именно:

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

Предположительно это связано с такой строкой:

«ЕСЛИ» чувствительно к регистру. Если вы попытаетесь запустить это с помощью /r , он не увидит запрос на рекурсию и всегда будет выполнять single .

Проблема в том, что ошибка о том, что файл не найден, произошла в журнале вывода (и на экране) раньше, чем указали команды echo. Поэтому я не знаю, шла ли оболочка WinXP cmd на несколько шагов вперед, или она выполняла синтаксический анализ для вызова exe во время запуска вызываемого файла bat или что-то в этом роде.

Оказалось, что на самом деле это плохой путь к .exe, который я запускал из сценария call'd bat, но отладочные операторы эха заставили меня подумать, что я был в какой-то более ранней части сценария. Как только я добавил правильный путь перед exe, все заработало

система не может найти метку пакета, указанную name_of_label

конечно существуют метки. Что вызывает эту ошибку?

на самом деле, вам нужно 2 условия для этого:

  • пакетный файл не должен использовать окончания строк CRLF
  • метка, к которой вы переходите, должна охватывать границу блока (в отличие от метки and :end, которая является просто ярлыком до конца вашего скрипта)

у меня такая же проблема раньше. Однако первопричиной был вовсе не CRLF. Это было потому, что в скрипте я выполнил внешнюю программу, такую как Ant, но не поставил CALL перед Ant. Итак, убедитесь, что вы CALL каждая внешняя программа, используемая в вашем пакетном скрипте.

основной причиной является процессор командной строки DOS (программа оболочки), принимает Символ конца строки UNIX как часть метки. Поскольку go to part никогда не использует это как метку, он никогда не найден, поскольку такая метка действительно не существует. Решение состоит в том, чтобы поместить дополнительное пространство в конце каждой целевой метки или даже лучше каждой строки. Теперь UNIX end of lines не приходят играть, так как пространство выступает в качестве разделителя, и все это работает.

Если пакетный файл имеет окончания строк unix (разделители строк), это иногда может произойти.

просто unix2dos это и проблема должна быть решена.

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

У меня была эта проблема после копирования команды запуска из Word и вставить в окно командной строки. Был вариант с " - " на фронте, и думал, что выглядит так же, как DOS "-" это не было :) после ввода "-" самостоятельно проблема была решена, и пакет работал . трудно найти проблему .

я столкнулся с аналогичной проблемой только что с a .файл cmd и Windows 8. Решение состояло в том, чтобы изменить все окончания строк на стиль CR+LF DOS. Проблема была запутанной, потому что пакетный файл в основном работал, и перестановка строк изменила эффект.

The .cmd файл выглядел так:

функция C вызовет ошибку "система не может найти указанную метку пакета". Странно это может уйти переставляя звонки. Изменение окончаний строк с 0x0A на 0x0D0A кажется, все исправил.

возможно, VonC означает "пакетный файл должен использовать окончания строк CRLF".

Системе не удается найти ярлык пакета, указанный name_of_label

Конечно лейбл существовал. Что вызывает эту ошибку?

ОТВЕТЫ

Ответ 1

На самом деле вам нужно 2 условия:

  • командный файл не должен использовать окончания строк CRLF
  • метка, к которой вы переходите, должна охватывать границу блока (в отличие от и: метка конца, которая является просто ярлыком до конца вашего скрипта)

Дэвид А. Грей упоминает в комментариях, видя (в Windows 10), что маршалответил в 2014 году (предположительно в Windows 7 или 8): сценарий/пакетная программа ( .bat или .cmd ), выполняемая без CALL , запускает преобразование eol.

За последние 35 лет я написал сотни пакетных сценариев, и единственная проблема, с которой у меня когда-либо возникали проблемы с отсутствием меток, была, когда разрывы строк файлов были преобразованы из Windows (CR/LF), которая работает, чтобы Unix (LF), чего нет.

Ответ 2

У меня такая же проблема. Однако основная причина не была CRLF. Это было потому, что в script я выполнил внешнюю программу, такую ​​как Ant, но не поставил CALL до Ant. Итак, убедитесь, что CALL каждая внешняя программа, используемая в вашей партии script.

Ответ 3

Коренной причиной является процессор командной строки DOS, (программа оболочки), принимает символ конца строки UNIX как часть метки. Поскольку переход на часть никогда не использует это как метку, он никогда не встречается, поскольку такой ярлык действительно не существует. Решение состоит в том, чтобы разместить дополнительное пространство в конце каждой целевой метки или даже лучше каждой строки. Теперь конец строк UNIX не появляется, поскольку пространство действует как разделитель, и все это работает.

Ответ 4

Если пакетный файл имеет окончание строки Unix (разделители строк), это иногда может произойти.

Просто unix2dos это и проблема должна быть решена.

Ответ 5

Вы также должны убедиться, что при вызове других скриптов вы используете CALL вместо их вызова в среде вызывающего абонента.

Ответ 6

Я столкнулся с аналогичной проблемой только с .cmd файлом и Windows 8. Решение состояло в том, чтобы изменить все концы строк на стиль CR + LF DOS. Проблема была запутанной, потому что пакетный файл в основном работал и перестраивал линии, изменил эффект.

Файл .cmd выглядел так:

Функция C вызовет ошибку "Система не может найти указанную пакетную метку". Как ни странно, это могло уйти, переставив вызовы. Изменение границ строк от 0x0A до 0x0D0A, похоже, исправило его.

Возможно, VonC означает "командный файл должен использовать окончания строки CRLF".

Ответ 7

У меня была эта проблема после копирования команды запуска из слова и вставки ее в окно команд. Был вариант с "-" спереди, и думал, что выглядит так же, как DOS "-" это было не так ". После ввода" - "сам вопрос был решен, и пакет работал. жесткий найти проблему.

Ответ 8

Немного другой вариант использования.

Я вызывал скрипт bat во время сборки Windows Server 2012 Server с использованием поставщика оболочки (OpenSSH). Теперь скрипт работал нормально с помощью cmd на подготовленной виртуальной машине (для остановки остановил сборку пакета и остановил ее, а затем подтвердил это). но с этими метками вызовов не было обнаружено проблем.

Концы строк были в порядке, CRLF (подтверждено в Notepadd++). Скрипт работал нормально и через командную строку. Более того, иногда он просто используется для нормальной работы, а иногда и для сбоя, но если для какого-то ярлыка произошел сбой, то сбой был последовательным.

Первоначально я только начал полностью удалять подпрограммы, расширив сам вызов и поместив код подпрограммы в строку. Я сделал это для всех случаев, когда был только один вызов (без дублирования кода).

Но, да, я наткнулся на один саб, который был вызван из 3,4 мест. Перепробовав все, вот что у меня сработало

PS: сценарий очень старый, но руководство нуждалось во мне, чтобы это работало через упаковщик (у нас есть план на второй день, чтобы заменить его на Ansible/Chef).

Я пытаюсь выяснить, как файл file1.bat может вызывать файл2.bat на указанной метке.

Я решил, что могу сделать это вот так:

Это работает. но я хочу назвать bat и ярлык из файла file1.bat. возможно ли это с помощью управляющего символа или кода ascii или чего-нибудь еще? как я пробовал

Любая помощь будет принята с благодарностью.

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

ОТВЕТЫ

Ответ 1

Вы можете передать метку, в которую хотите перейти, в качестве параметра

Ответ 2

Вы можете использовать странный трюк!
Вы можете получить метку во вторичной партии без вызова ее во вторичной партии!

Кажется, нет причин, по которым вызывается метка, и почему элемент управления должен возвращаться в first.bat, поскольку вторая партия была вызвана без CALL.
Причиной для первой точки является внутренний код команды goto .
Вторая точка может быть объяснена, так как есть один вызов до фиктивной метки в первом командном файле.
exit /b в second.bat возвращается непосредственно к вызову (строка 3) first.bat не к вызову second.bat в строке 7

EDIT: Как отключить нечетное поведение

если вы добавите команду в second.bat , она больше не будет скрывать переход к метке в файле second.bat.

second.bat & rem изменит вывод на OUTPUT

Ответ 3

Существует несколько методов или трюков, которые позволяют это сделать. В этом решении трюк заключается в изменении контекста текущей программы на второй пакетный файл. После этого изменения все метки во втором командном файле становятся локальными метками запущенной программы, поэтому они могут быть вызваны непосредственно с помощью обычной команды call :label , которая также может включать аргументы полностью стандартным образом. Контекст запущенной программы должен быть восстановлен до завершения программы.

Способ изменения контекста состоит в том, чтобы просто переименовать второй пакетный файл с тем же именем первого (и переименовать первое в другое имя), поэтому, когда процессор пакетного файла ищет метку, он действительно ищет содержимое второго файла! Перед завершением программы файлы должны быть переименованы в исходные имена. Ключевым моментом, который делает этот метод, является то, что оба набора команд переименования (и весь код между ними) должны быть заключены в круглые скобки; таким образом, код сначала разбирается, а затем выполняется из памяти, поэтому переименование файлов на диске не влияет на него. Конечно, эта точка означает, что доступ к значениям всех переменных в коде должен выполняться с помощью отложенного! Расширения! (или используя трюк call %%variable%% ).

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

EDIT: восстановление файлов при возникновении ошибки времени выполнения

Как указано в комментарии, если ошибка во время выполнения происходит после переименования файлов, файлы не переименовываются в исходные имена; однако очень легко обнаружить эту ситуацию из-за наличия файла second.bat и восстановить файлы, если такой файл не существует. Этот тест может быть выполнен в секции супервизора, которые запускают исходный код в отдельном контексте cmd.exe, поэтому этот раздел всегда будет корректно завершен, даже если исходный код был отменен с ошибкой.

Исходный код CALLAT.bat:

Ответ 5

Как я уже сказал в комментарии, который я приложил к моему ответу, я наградил награду, потому что @NicoBerrogorry потратил время на разработку отличного решения и предоставил полную рецензию.

Тем не менее, была одна синтаксическая ошибка, которую он упустил, вероятно, потому, что он не использует файлы CMD, а я почти полностью отказался от файлов BAT. Следующий CALLAT script включает в себя одну коррекцию и четыре улучшения.

Читайте также: