Перенаправление вывода консольного приложения, запускаемого через ярлык.
У меня на домашнем сервере установлен VirtualBox, под управлением которого крутятся три виртуальные машины. Одна машина выделена под haproxy, на второй трудятся VPN сервер от SoftEther и FuguHub, а на третьей - всевозможный софт, начиная от облачного хранилища NextCloud и заканчивая Transmission. Но сейчас не об этом.
Если у вас есть виртуалки, обязательно наступит момент, когда захочется ими управлять. У меня на сервере установлен Windows 10 Pro
, поэтому долгое время я просто использовал подключение к удаленному рабочему столу: подключался по RDP
, запускал VirtualBox
и выполнял требуемые действия. Но, как обычно, появилось смутное желание как-нибудь улучшить (?!), как говорится, сложившиеся практики. Однако, сейчас тоже не об этом.
В поставке VirtualBox
имеется специальная программа с говорящим названием VBoxWebSrv
. Эта программа предоставляет доступ к основному API (это то самое API, которое используется стандартным GUI клиентом VirtualBox
), выступая в качестве HTTP
сервера, который может обрабатывать SOAP
запросы.
Естественно, сторонние разработчики не могли оставить без внимания такую возможность и, как результат, стали появляться утилиты для удаленного управления VirtualBox
, такие, как RemoteBox и phpVirtualBox. И, конечно же, все эти утилиты требуют, чтобы в обязательном порядке был запущен экземпляр VBoxWebSrv
.
В первое (и довольно длительное) время, я довольствовался тем, что для запуска этой программы сделал ярлык на Рабочем Столе. Все было здорово и замечательно: запустил один раз web сервер VirtualBox
и пользуйся утилитами удаленного управления виртуальными машинами. Но потом я вычитал где-то в "этих ваших интернетах", что если перенаправить вывод VBoxWebSrv
в специальное устройство с многозначительным названием nul
, то можно получить значительный выигрыш в производительности. Сделать это перенаправление из командной строки не вызывает никаких затруднений:
vboxwebsrv > nul
Всего и делов-то. А вот как это сделать при запуске с использованием ярлыка?
Когда выполняется консольное приложение, а VBoxWebSrv
является именно консольным приложением, то, обычно, ввод/вывод осуществляется при помощи так называемых стандартных устройств ввода/вывода: в случае ввода - это клавиатура, а в случае вывода - экран (консоли). Но эти самые операции ввода/вывода можно перенаправить, например, осуществить ввод не с клавиатуры, а из файла (предварительно записав в него все, что нужно), или же вывод осуществить не на экран (окно консоли), а, например, в файл или в другое (именованное) устройство. Перенаправлением занимается командный процессор, но для этого ему надо дать указания при помощи специальных символов: >
, >>
, <
, <<
.
При запуске же программы из ярлыка командный процессор не имеет возможности обработать указания о необходимости перенаправления вывода (или ввода). Все, что указывается после имени выполняемого файла программы, рассматривается исключительно в качестве параметров, передаваемых именно этой самой программе.
И тут следует вспомнить, что командный процессор сам по себе тоже является программой, которой можно передавать параметры, и которую, конечно же, можно запускать из ярлыка. У стандартного командного процессора Windows cmd.exe
есть ключ, который указывает ему, что надо выполнить команду, переданную в качестве параметра, после чего завершить выполнение. Это ключ /C
. То есть, можно написать так:
cmd /C "vboxwebsrv"
и командный процессор выполнит программу vboxwebsrv
(если найдет ее) и, после ее завершения, сам прекратит свое выполнение. А самое интересное (и важное для нас), что эту команду можно слегка подкорректировать и написать примерно так:
cmd /C "vboxwebsrv > nul"
и весь вывод программы vboxwebsrv
будет перенаправлен в устройство с именем nul
.
VBoxWebSrv
, а командный процессор, которому, при помощи параметра, будет предписано выполнить нужную программу с требуемым перенаправлением вывода.
И, в завершении, хотелось бы отметить следующее: полый путь к VBoxWebSrv
указывать не пришлось, потому что у ярлыка есть поле Start in
. Если же надо указать полный путь, да еще в этом пути будут присутствовать пробелы, то могут возникнуть проблемы с использованием вложенных кавычек ("
). Но и тут есть выход: существует ключ /S
, который специальным образом обрабатывает вложенные кавычки - он отбрасывает первую кавычку (если она - первый символ передаваемого в cmd.exe
параметра) и последнюю обнаруженую в параметре кавычку. Поэтому такая команда:
C:\Windows\System32\cmd.exe /S /C ""C:\Program Files\Oracle\VirtualBox\VBoxWebSrv.exe" > nul"
будет замечательным образом работать. И еще один важный момент: /S
должен стоять перед /C
. Вот теперь, пожалуй, все...