O Bash tem <(..)
para substituição de processo. Qual é o equivalente do Powershell?
Eu sei que existe $(...)
, mas ele retorna uma string, enquanto <(..)
retorna um arquivo que o comando externo pode ler, e é o que ele espera.
Também não estou procurando uma solução baseada em pipe, mas algo que eu possa colocar no meio da linha de comando.
powershell
IttayD
fonte
fonte
Write-Output "The BITS service is $(Get-Service bits | select -ExpandProperty Stauts)"
para obter o status do serviço BITS sem carregá-lo em uma variável primeiro. Olhando para processo de substituição, isso não é exatamente o mesmo, mas ainda pode resolver o problema que você está enfrentandopsftp.exe
para transferências de SFTP: sua-b
opção exige que você forneça comandos para executar no servidor por meio de um arquivo , o que é inconveniente, se você deseja apenas executar, digamosmget *
,. Se o PowerShell tivesse substituição de processo, você seria capaz de fazer algo parecidopsftp.exe -l user -p password somehost -b <( "mget *" )
.Respostas:
Esta resposta NÃO é para você , se:
- raramente, se alguma vez precisar usar CLIs externas (o que geralmente vale a pena procurar - os comandos nativos do PowerShell funcionam muito melhor juntos e não precisam desse recurso).
- não está familiarizado com a substituição de processos de Bash.
Esta resposta é para você , se você:
- costuma usar CLIs externas (por hábito ou devido à falta de (boas) alternativas nativas do PowerShell), especialmente ao escrever scripts.
- estão acostumados e apreciam o que a substituição de processos do Bash pode fazer.
- Atualização : agora que o PowerShell também é suportado nas plataformas Unix, esse recurso é de interesse crescente - consulte esta solicitação de recurso no GitHub, o que sugere que o PowerShell implemente um recurso semelhante ao processo de substituição.
No mundo Unix, no Bash / Ksh / Zsh, uma substituição de processo oferece tratamento da saída do comando como se fosse um arquivo temporário que se limpa; por exemplo
cat <(echo 'hello')
, ondecat
vê a saída doecho
comando como o caminho de um arquivo temporário que contém a saída do comando .Embora os comandos nativos do PowerShell não tenham necessidade real desse recurso, ele pode ser útil ao lidar com CLIs externas .
Emular o recurso no PowerShell é complicado , mas pode valer a pena, se você precisar dele com frequência.
Imagine uma função nomeada
cf
que aceita um bloco de script, executa o bloco e grava sua saída em um temp. arquivo criado sob demanda e retorna a temp. caminho do arquivo ; por exemplo:Este é um exemplo simples que não ilustra bem a necessidade desse recurso. Talvez um cenário mais convincente seja o uso de
psftp.exe
transferências SFTP: seu uso em lote (automatizado) requer o fornecimento de um arquivo de entrada contendo os comandos desejados, enquanto esses comandos podem ser facilmente criados como uma string em movimento.Para ser o mais amplamente possível possível com utilitários externos, a temperatura. arquivo deve usar UTF-8 codificação sem uma BOM (marca de ordem de bytes) por padrão, mas você pode solicitar um BOM UTF-8 com
-BOM
, se necessário.Infelizmente, o aspecto de limpeza automática das substituições de processos não pode ser emulado diretamente , portanto, é necessária uma chamada de limpeza explícita ; a limpeza é realizada chamando
cf
sem argumentos :Para uso interativo , você pode automatizar a limpeza adicionando a chamada de limpeza à sua
prompt
função da seguinte forma (aprompt
função retorna a sequência de prompt , mas também pode ser usada para executar comandos nos bastidores toda vez que o prompt é exibido, semelhante ao do Bash$PROMPT_COMMAND
variável); para disponibilidade em qualquer sessão interativa, adicione o seguinte e a definiçãocf
abaixo ao seu perfil do PowerShell:Para uso em scripts , para garantir que a limpeza seja realizada, o bloco que usa
cf
- potencialmente todo o script - precisa ser empacotado em um blocotry
/finally
, no qualcf
sem argumentos é chamado para limpeza:Aqui está a implementação : função avançada
ConvertTo-TempFile
e seu alias sucintocf
:Nota : O uso de
New-Module
, que requer PSv3 +, para definir a função por meio de um módulo dinâmico garante que não haja conflitos de variáveis entre os parâmetros da função e as variáveis referenciadas dentro do bloco de script passado.Observe a capacidade de especificar opcionalmente um caminho [arquivo] de saída e / ou extensão de nome de arquivo.
fonte
psftp.exe
, o que me levou a escrevê-lo. Embora seja preferível fazer tudo de forma nativa no PowerShell, isso nem sempre é possível; invocar CLIs externas do PowerShell faz e continuará a acontecer; se você estiver lidando repetidamente com CLIs que exigem entrada de arquivo que (mais) podem ser facilmente construídas na memória / por outro comando, a função nesta resposta pode facilitar sua vida.Quando não está entre aspas duplas,
$(...)
retorna um Objeto do PowerShell (ou melhor, o que for retornado pelo código incluído), avaliando o código incluído primeiro. Isso deve ser adequado para seus propósitos ("algo [I] pode ficar no meio da linha de comando"), assumindo que a linha de comando seja o PowerShell.Você pode testar isso canalizando várias versões para
Get-Member
, ou apenas produzindo diretamente.Quando colocado entre aspas duplas, como você notou, `" $ (...) "retornará apenas uma string.
Dessa forma, se você quiser inserir, digamos, o conteúdo de um arquivo diretamente em uma linha, poderá usar algo como:
fonte
Get-Content <(Get-ChildItem)
Get-ChildItem | Get-Content
funciona perfeitamente? Ou você poderia tentarGet-Content (Get-ChildItem).FullName
o mesmo efeito? Você pode abordar isso de uma visão completamente influenciada por outra abordagem de script.