Bash имеет <(..)
для процесса замены. Каков эквивалент Powershell?
Я знаю, что это так $(...)
, но он возвращает строку, в то время как <(..)
возвращает файл, из которого внешняя команда может прочитать, чего он и ожидает.
Я также не ищу решение на основе конвейера, но что-то, что я могу вставить в середину командной строки.
powershell
IttayD
источник
источник
Write-Output "The BITS service is $(Get-Service bits | select -ExpandProperty Stauts)"
чтобы получить статус службы BITS без предварительной загрузки ее в переменную. Глядя на процесс подстановки, это не совсем то же самое, но оно может решить проблему, с которой вы столкнулисьpsftp.exe
для передачи SFTP: его-b
вариант требует , чтобы обеспечить команды для запуска на сервере с помощью файла , что неудобно, если вы просто хотите запустить, скажем,mget *
. Если в PowerShell есть подстановка процессов, вы сможете сделать что-то подобноеpsftp.exe -l user -p password somehost -b <( "mget *" )
.Ответы:
Этот ответ НЕ для вас , если вы:
- редко, если вообще когда-либо, нуждаетесь в использовании внешних интерфейсов командной строки (к которым, как правило, стоит стремиться - собственные команды PowerShell играют намного лучше вместе и не нуждаются в такой возможности).
- не знакомы с заменой процесса Баша.
Этот ответ для вас , если вы:
- часто используете внешние CLI (будь то по привычке или из-за отсутствия (хороших) альтернатив PowerShell-нативных), особенно при написании сценариев.
- привыкли и ценят то, что может сделать замена процесса в Bash.
- Обновление : теперь, когда PowerShell поддерживается и на платформах Unix, эта функция вызывает все больший интерес - см. Этот запрос на GitHub.Это означает, что PowerShell реализует функцию, аналогичную процессу замещения.
В мире Unix, в Bash / Ksh / Zsh, подстановка процесса предлагает обрабатывать вывод команды, как если бы это был временный файл, который очищается после себя; например
cat <(echo 'hello')
, гдеcat
видит выходные данныеecho
команды как путь к временному файлу, содержащему выходные данные команды .Хотя для собственных команд PowerShell нет реальной необходимости в такой функции, она может быть полезна при работе с внешними интерфейсами командной строки .
Эмуляция функции в PowerShell громоздка , но, возможно, она того стоит, если вам часто это нужно.
Представьте себе функцию с именем,
cf
которая принимает блок скрипта, выполняет блок и записывает свои выходные данные в temp. файл создается по требованию и возвращает темп. путь к файлу ; например:Это простой пример, который не иллюстрирует необходимость такой функции. Возможно, более убедительным сценарием является использование
psftp.exe
для передач SFTP: его пакетное (автоматическое) использование требует предоставления входного файла, содержащего нужные команды, тогда как такие команды могут быть легко созданы в виде строки на лету.Чтобы быть максимально совместимым с внешними утилитами, насколько это возможно, временная. Файл должен использовать UTF-8 кодировке без BOM (метка порядка байтов) по умолчанию, хотя вы можете запросить BOM UTF-8 с
-BOM
, если это необходимо.К сожалению, аспект автоматической очистки замен процесса не может быть напрямую эмулирован, поэтому необходим явный вызов очистки ; уборка производится по телефону
cf
без аргументов :Для интерактивного использования вы можете автоматизировать очистку, добавив вызов очистки в вашу
prompt
функцию следующим образом (prompt
функция возвращает строку приглашения , но ее также можно использовать для выполнения закулисных команд при каждом отображении приглашения, аналогично Bash.$PROMPT_COMMAND
переменная); для доступности в любом интерактивном сеансе добавьте следующее, а также приведенноеcf
ниже определение в свой профиль PowerShell:Для использования в сценариях , чтобы гарантировать выполнение очистки, блок, который использует
cf
- возможно весь сценарий - должен быть заключен в блокtry
/finally
, в которомcf
без аргументов вызывается для очистки:Вот реализация : расширенная функция
ConvertTo-TempFile
и ее краткий псевдонимcf
:Примечание : использование
New-Module
, которое требует PSv3 +, для определения функции через динамический модуль гарантирует, что не может быть никаких переменных конфликтов между параметрами функции и переменными, на которые есть ссылки в переданном блоке скрипта.Обратите внимание на возможность при желании указать выходной путь [файл] и / или расширение имени файла.
источник
psftp.exe
, что побудило меня написать это. Несмотря на то, что в PowerShell желательно все делать изначально, это не всегда возможно; вызов внешних CLI из PowerShell делает и будет происходить; если вы постоянно сталкиваетесь с CLI, которые требуют ввода файла, который (более) легко может быть создан в памяти / другой командой, функция в этом ответе может облегчить вашу жизнь.Когда не заключены в двойные кавычки,
$(...)
возвращает объект PowerShell (или, скорее, все, что возвращается в прилагаемом коде), сначала оценивая вложенный код. Это должно подходить для ваших целей («что-то [I] может застрять в середине командной строки»), предполагая, что командной строкой является PowerShell.Вы можете проверить это, передавая различные версии
Get-Member
или даже просто выводя их напрямую.Когда вы заключили в двойные кавычки, как вы заметили, `" $ (...) "просто вернет строку.
Таким образом, если вы хотите вставить, скажем, содержимое файла прямо в строку, вы можете использовать что-то вроде:
источник
Get-Content <(Get-ChildItem)
Get-ChildItem | Get-Content
хорошо работает? Или вы могли бы попытатьсяGet-Content (Get-ChildItem).FullName
на тот же эффект? Возможно, вы подходите к этому с точки зрения, находящегося под сильным влиянием другого сценариев.