Подтвердить что ты не робот

Что такое `cmd/s`?

Командная строка Windows (cmd.exe) имеет необязательный параметр /s, который изменяет поведение /c (запустит определенную команду, а затем выйдет ) или /k (запустите определенную команду, а затем отобразите приглашение оболочки). Этот параметр /s, очевидно, имеет какое-то отношение к какому-то управлению тайной кавычкой.

Документы запутывают, но насколько я могу судить, когда вы делаете cmd /c something, а something содержит кавычки, тогда по умолчанию cmd иногда отделяет эти кавычки, а /s говорит, чтобы он оставил их в покое.

Я не понимаю, когда удаление цитаты сломает что-нибудь, потому что будет необходимо только время /s ( "подавить поведение по умолчанию для котировки" ). Он удаляет только кавычки под определенным тайным набором условий, и одним из таких условий является то, что первым символом после /c должен быть кавычка. Поэтому он не удаляет кавычки вокруг аргументов; он либо удаляет кавычки по пути к EXE, в котором вы работаете, либо по всей командной строке (или, возможно, около первой половины командной строки, что было бы странно).

  • Если указан путь к EXE, например. cmd /c "c:\tools\foo.exe" arg1 arg2, тогда цитаты не нужны, и если cmd хочет их удалить, то штраф. (Он не удалит их, если у пути есть пробел в имени - это еще один из тайных правил.) Я не могу представить никаких причин для подавления удаления цитат, поэтому /s кажется ненужным.
  • Если вся строка командной строки цитируется, например. cmd /c "foo.exe arg1 arg2", то кажется, что удаление цитат было бы необходимо, поскольку в системе не было EXE с именем foo.exe arg1 arg2; поэтому кажется, что отказ от цитаты с помощью /s действительно нарушит ситуацию. (На самом деле, однако, это не нарушает вещи: cmd /s /c "foo.exe arg1 arg2" работает нормально.)

Есть ли какая-то тонкость в /s, которая ускользает от меня? Когда это когда-нибудь понадобится? Когда это будет даже иметь значение?

4b9b3361

Ответ 1

Cmd/S очень полезен, так как это избавляет вас от беспокойства о "цитировании цитат". Напомним, что аргумент /C означает "выполнить эту команду, как если бы я набрал ее в приглашении, а затем выйти".

Итак, если у вас есть сложная команда, которую вы хотите передать в CMD.exe, вам либо нужно помнить правила цитирования аргументов CMD, и надлежащим образом избегать всех котировок, либо использовать /S, который запускает специальный не-парсинг правило "Снять первый и последний " и обрабатывать все остальные символы как команду для выполнения без изменений".

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

Пример:

Использовать встроенную оболочку: это выполняется, если вы набрали DEL /Q/S "%TMP%\TestFile" в командной строке:

CMD.exe /S /C " DEL /Q/S "%TMP%\TestFile" "

Это выполняет SomeCommand.exe перенаправление стандартного вывода в файл temp и стандартную ошибку на одно и то же место:

CMD.exe /S /C " "%UserProfile%\SomeCommand.exe" > "%TMP%\TestOutput.txt" 2>&1 "

Итак, что дает /S вам дополнительное? В основном это избавляет вас от необходимости беспокоиться о цитировании цитат. Это также помогает там, где вы не уверены, например, что переменная среды содержит символы кавычек. Просто скажите /S и добавьте дополнительную цитату в начале и конце.

Смутно Связано: $* в Bourne Shell.

Некоторые фон

Напомним, что список аргументов main() - это C-ism и Unix-ism. Оболочка Unix/Linux (например, Bourne Shell и т.д.) Интерпретирует командную строку, исключает аргументы, расширяет подстановочные знаки, такие как *, на списки файлов и передает список аргументов вызываемой программе.

Итак, если вы скажете:

$ vi *.txt

Команда vi видит, например, следующие аргументы:

vi
a.txt
b.txt
c.txt
d.txt

Это связано с тем, что unix/linux работает внутренне на основе "списка аргументов".

Windows, которая в конечном итоге получается из CP/M и VAX, не использует эту систему внутренне. В операционной системе командная строка представляет собой всего лишь одну строку символов. Ответственность вызываемой программы заключается в интерпретации командной строки, расширении файловых глобусов (* и т.д.) И обработке нечетких цитируемых аргументов.

Итак, аргументы, ожидаемые C, должны быть взломаны библиотекой времени выполнения C. Операционная система предоставляет только одну строку с аргументами in, и если ваш язык не является C (или даже если он есть), он не может быть интерпретирован как аргументы, разделенные пробелами, указанные в соответствии с правилами оболочки, но как нечто совершенно иное.

Ответ 2

Вот пример того, как это может измениться.

Предположим, что у вас есть два исполняемых файла: c:\Program.exe и c:\Program Files\foo.exe.

Если вы скажете

cmd /c "c:\Program Files\foo"

вы запустите foo.exe (без аргументов), тогда как если вы скажете

cmd /s /c "c:\Program Files\foo"

в качестве аргумента вы выполните Program.exe с Files\foo.

(Как ни странно, в первом примере, если foo.exe не существовало, вместо этого выполнялся Program.exe.)

Добавление:, если вы набрали

 c:\Program Files\foo

в командной строке вы будете запускать Program.exe (как это происходит с cmd/s/c), а не foo.exe (как это происходит только с cmd/c). Поэтому одной из причин использования /s было бы, если вы хотите убедиться, что команда анализируется точно так же, как если бы она была введена в командной строке. Вероятно, это скорее всего будет желательным в сценарии в вопросе, связанном с Michael Burr, где cmd.exe запускается CreateProcess, а не из командного файла или самой командной строки.

То есть, если вы скажете

CreateProcess("cmd.exe", "cmd /s /c \"" MY_COMMAND "\"", ...)

тогда строка MY_COMMAND будет анализироваться точно так же, как если бы она была введена в командной строке. Если вы берете ввод с командной строки от пользователя или если вы являетесь библиотекой, обрабатывающей командную строку, предоставляемую приложением, это, вероятно, хорошая идея. Например, функция C runtime library system() может быть реализована таким образом.