#php #windows #terminal
#php #Windows #терминал
Вопрос:
У меня есть файлы с допустимыми именами файлов. Если бы они не были допустимыми, их было бы невозможно сохранить в моей файловой системе. Windows. NTFS.
Например:
E:videosHappy Fun Time!.mp4
Если я сделаю:
if (file_exists('E:videosHappy Fun Time!.mp4'))
Затем PHP «видит» файл; он существует. Хорошо.
Однако, если я попытаюсь фактически использовать путь к файлу, например, отправив его в команде:
shell_exec('test.exe --input=' . escapeshellarg('E:videosHappy Fun Time!.mp4'));
… затем test.exe получает / отправляется:
test.exe --input="E:videosHappy Fun Time .mp4"
Она превратила «!» в пробел, что делает его более недействительным.
Я знаю, что они делают это по соображениям безопасности, и что правильное экранирование в Windows — это что-то вроде кошмара. Тем не менее, это все еще остается проблемой, поскольку я не могу ссылаться на какой-либо файл, содержащий «!» и, возможно, также другие допустимые символы.
При запуске такого рода вещей я обычно получаю «meh… на самом деле нам не хочется поддерживать реакцию разработчиков на вашу «странную ОС». Они действуют так, как будто Windows — это какой-то непонятный дистрибутив Linux, а не настольная ОС № 1 в мире. Даже если вы думаете, что это отстой, с чем я полностью согласен, кстати, разве задача кодирования не «забавна» в некотором роде для умных программистов? Довольно неприятно, когда люди ведут себя так, как будто PHP и другое программное обеспечение кроссплатформенны, когда на самом деле это «Linux-first, и, возможно, какая-нибудь полуфабрикатная поддержка Windows, если у нас есть время и хочется». (Но я остановлюсь на этом, опасаясь пометки «rant».)
В комментариях пользователей к руководству по PHP предлагаются различные безумные решения, как это обычно бывает. Я действительно не чувствую себя комфортно, используя любую из них, как по соображениям безопасности, так и потому, что просто странно полагаться на какой-то комментарий, отправленный пользователем много лет назад, вместо реальной функции PHP для выполнения этой критической задачи экранирования / защиты аргументов / путей терминала.
Как может быть, что file_exists
может безопасно проверять ее существование, даже с помощью «!»? file_exist
Есть ли какой-то внутренний код, который безопасно и корректно проверяет все допустимые имена файлов, тогда как escapeshellarg()
по какой-то причине этого не хватает? Или file_exist
«запрашивает ОС» или «запрашивает файловую систему» каким-либо встроенным способом, который полностью обходит необходимость обрабатывать экранирование строки пути к файлу?
Я не знаю, что теперь делать. Какой-то парень ссылался на исходный код ReactOS, но это не PHP, и если это такое отличное решение, почему это не было включено в сам PHP? Я не понимаю, почему так много функций PHP никогда не обновляются / не улучшаются или не добавляются новые улучшенные, вместо того, чтобы каждый отдельный «PHPhant» (так я называю себя и других пользователей PHP) пытался собрать воедино свое собственное решение для таких важных и распространенных задач?
Комментарии:
1. Я не знаком с тем, что
!
делает в командной строке Windows, но если вы знаете, что это безопасно, вы могли бы заменить ее заполнителем перед вызовом escape, то замените заполнитель обратно. Мне пока не удалось найтиfile_exists
определение в исходном коде PHP. Также, возможно, одно из решений на php.net/manual/en/function.escapeshellarg.php#123718 решает это?2. Вам, вероятно, потребуется
^!
экранирование курсора, если вы продолжаете использовать cmd.exe вместо Powershell с его более последовательным «синтаксическим анализом» командной строки.3. @mario Я не использую cmd.exe. PHP работает. И Windows. Кроме того, в PowerShell есть множество странных проблем, с которыми я столкнулся на собственном опыте, пытаясь заставить PHP и себя использовать его. И теперь, когда Windows Terminal становится чем-то особенным, PowerShell, как я полагаю, в любом случае уходит в прошлое. Но опять же, я не использую cmd.exe. Это то, что… используется.
4. @user3783243 Я начал использовать это сейчас, но мне кажется чрезвычайно странным использовать сторонний код вместо собственной функции PHP: github.com/johnstevenson/winbox-args