Для чего нужен `cmd / s`? - PullRequest
       1

Для чего нужен `cmd / s`?

28 голосов
/ 26 марта 2012

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

Документы сбивают с толку, но, насколько я могу судить, когда вы делаете cmd /csomething, а 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, которая ускользает от меня? Когда это будет необходимо? Когда это вообще будет иметь значение?

Ответы [ 2 ]

16 голосов
/ 26 марта 2012

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 перенаправляет стандартный вывод во временный файл и стандартную ошибку в одно и то же место:

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

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

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

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

* 1028Напомним, что список аргументов 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 библиотека времени выполнения.Операционная система предоставляет только одну строку с аргументами в, и если ваш язык не является C (или даже если это так), он не может интерпретироваться как аргументы, разделенные пробелом, заключенные в соответствии с правилами оболочки, но как нечто совершенно иное.

10 голосов
/ 26 марта 2012

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

Предположим, у вас есть два исполняемых файла: 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 будет то, что вы хотите убедиться, что команда анализируется точно так же, как если бы она вводилась в командной строке.Это, вероятно, более вероятно, будет желательно в сценарии в вопросе, связанном с Майклом Берром, где cmd.exe запускается CreateProcess, а не из пакетного файла или самой командной строки.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...