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

Как получить доступ к файлам в Powershell с специальными символами?

Я вызываю powershell из приложения Java (через командную строку Windows) для чтения различных атрибутов файла.

например.

powershell (get-item 'C:\Users\erlpm\Desktop\Temp\s p a c e s.txt').creationTime

Я включаю путь файла в одинарные кавычки, потому что он может содержать пробелы. Он работал нормально, пока не встретил путь к файлу, содержащий квадратные скобки, которые, похоже, интерпретируются как подстановочный знак. Мне удалось решить эту проблему, добавив параметр -literalPath:

powershell (get-item -literalpath 'C:\Users\erlpm\Desktop\Temp\brackets[].txt').creationTime

До сих пор так хорошо... Но пути к файлам могут также содержать одинарные кавычки, знаки доллара, амперсанды,... и все эти символы, похоже, имеют определенную функцию в powershell, для которой параметр -literalPath не работает. Я попытался включить путь с двойными кавычками или экранированием с символом `, но это не решило мою проблему: - (

Любые предложения о том, как передать путь к файлу Powershell, который может содержать пробелы, одинарные кавычки, квадратные скобки, амперсанды, знаки доллара и т.д.?

Update: Кто-то здесь уже показал мне, как заставить его работать изнутри Powershell, но почему-то ответ был удален?
Во всяком случае, я создал файл с именем $ & ' [].txt. Эта форма работает внутри Powershell (необходимо, чтобы избежать &):

    PS C:\Users\erlpm> Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"


    Directory: C:\Users\erlpm\Desktop\Temp


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2012-08-23     14:22          0 $ & ' [].txt

Но когда я выполняю ту же команду Powershell через командную строку Windows,...

C:\Users\erlpm>powershell Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"

... Я получаю эту ошибку:

    Ampersand not allowed. The & operator is reserved for future use; use "&" to pass ampersand as a string.
At line:1 char:55
+ Get-Item -LiteralPath C:\Users\erlpm\Desktop\Temp\`$ & <<<<  ' [].txt
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : AmpersandNotAllowed

Использование параметра -command и установка команды powershell между {} дает точно такое же сообщение об ошибке...

C:\Users\erlpm>powershell -command {Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"}
4b9b3361

Ответ 1

Если вы можете записать путь к временному txt файлу, то будет выполнено следующее:

(get-item -literalpath (gc 'C:\Temp\path.txt')).creationTime

Файл @C:\Temp\path.txt содержит путь со специальными символами в нем, кроме этого, я думаю, вам придется избегать каждого специального символа на основе каждого пути.

В дополнение к взлому выше, похоже, Powershell V3 может помочь здесь с добавлением новой функции языка "волшебный параметр". В частности, см. Раздел "Легкое повторное использование командных строк из Cmd.exe" здесь и потому, что я ненавижу ссылку-гниль, вот оно, бесстыдно воспроизводится ниже:

Легкое повторное использование командных строк из Cmd.exe

В сети полно командных строк, написанных для Cmd.exe. Эти команды линии работают достаточно часто в PowerShell, но когда они включают определенные символы, например. точка с запятой (;) знак доллара ($) или фигурные скобки, вы должны внести некоторые изменения, возможно, добавив некоторые кавычки. Эта казалось, был источником многих незначительных головных болей.

Чтобы помочь решить этот сценарий, мы добавили новый способ "избежать" разбор командных строк. Если вы используете магический параметр -%, мы остановимся наш обычный синтаксический анализ вашей командной строки и переход к чему-то большому проще. Мы не сопоставляем кавычки. Мы не останавливаемся в точке с запятой. Мы Не расширяйте переменные PowerShell. Мы расширяем переменные среды если вы используете синтаксис Cmd.exe(например,% TEMP%). Помимо этого, аргументы до конца строки (или трубы, если вы являетесь трубопроводом): прошло как есть. Вот пример:

echoargs.exe --% %USERNAME%,this=$something{weird}
Arg 0 is <jason,this=$something{weird}>

Ответ 2

Это действительно вопрос о escape-последовательности cmd.exe. Сочетание cmd и powershell string escaping - полный кошмар. После нескольких попыток я получил ваш конкретный пример:

C:\Users\latkin>powershell.exe -nologo -noprofile -command ^&{ dir -LiteralPath ^"""".\`$ & ' [].txt"" }

    Directory: C:\Users\latkin
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/23/2012   8:46 AM          0 $ & ' [].txt

Полностью интуитивно понятен, правильно?

Вы можете проводить 15-минутную борьбу с escape-последовательностями каждый раз, или вы можете попробовать другие оценки.

Поместите имя файла в текстовый файл и прочитайте его оттуда.

C:\> powershell.exe -command "&{dir -literal (gc .\filename.txt)  }"

или

Используйте script

C:\> powershell.exe -file .\ProcessFiles.ps1  # in processfiles.ps1 you are in fully powershell environment, so escaping is easier

или

Использовать -EncodedCommand

См. powershell.exe -? (последний отображаемый элемент) или http://dmitrysotnikov.wordpress.com/2011/07/06/passing-parameters-to-encodedcommand/

Ответ 3

Этот поток составляет 5 лет, поэтому, возможно, времена изменились, но текущий ответ, который работал у меня, заключался в использовании символа обратного хода (`) для выхода из специального символа.

В моем случае это был знак доллара в пути к каталогу, который был неудачным. Поставив обратную линию перед знаком доллара, все сработало.

До:

$dir = "C:\folder$name\dir"  # failed

После:

$dir = "C:\folder`$name\dir" # succeeded