Como inserir um comando de várias linhas


425

É possível dividir uma linha de comando do PowerShell em várias linhas?

No Visual Basic, posso usar o sublinhado ( _) para continuar o comando na próxima linha.


3
A pergunta "por que não barras invertidas" é abordada muito bem no PowerShell in Action de Bruce Payette ; grande livro. Bruce tem um amplo conhecimento da história das linguagens de programação. Ansioso pela V2 deste livro.
Jay Bazuzi


1
Desculpe se é offtopic, mas se você deseja enviar o script com o shcomando, as convenções do bash são válidas para que você possa usar barra invertida. Nesse caso, seu script também deve ter finais de estilo unix.
precisa

basta usar `personagem para comando separado em várias linhas
Asad Shakeel

Respostas:


634

Você pode usar um espaço seguido pelo acento grave (backtick):

Get-ChildItem -Recurse `
  -Filter *.jpg `
  | Select LastWriteTime

No entanto, isso só é necessário nesses casos, como mostrado acima. Geralmente, você obtém a continuação automática da linha quando um comando não pode ser sintaticamente completo nesse ponto. Isso inclui iniciar um novo elemento de pipeline:

Get-ChildItem |
  Select Name,Length

funcionará sem problemas, pois após o |comando não poder ser concluído, pois está faltando outro elemento do pipeline. A abertura de chaves ou qualquer outro tipo de parênteses permitirá a continuação da linha diretamente:

$x=1..5
$x[
  0,3
] | % {
  "Number: $_"
}

Semelhante à |vírgula também funcionará em alguns contextos:

1,
2

Porém, lembre-se, semelhante à Inserção automática de ponto e vírgula do JavaScript , há algumas coisas que são quebradas da mesma forma porque a quebra de linha ocorre em um ponto em que é precedida por uma declaração válida:

return
  5

não funciona.

Finalmente, as strings (em todas as variedades) também podem se estender além de uma única linha:

'Foo
bar'

Eles incluem as quebras de linha na sequência, então.


4
E não esqueça de mencionar que alguns outros tokens também atuam como continuadores de linha, por exemplo, |e {.
21410 Keith Hill

1
@ Keith: Obrigado, eu incluí. Provavelmente eram óbvias demais para serem mencionadas ;-) #
Joey

16
Não, é bom ter esses outros caracteres documentados para referência futura.
21710 Keith Hill

1
@JackDouglas: Você pode ter uma quebra de linha diretamente após o parêntese de abertura, mas não dentro da expressão antes do operador, aparentemente. Dito isto, acredito que seja um descuido na gramática.
Joey

10
A continuação de linha não funciona no painel de comandos ISE, aparentemente.
Khouri Giordano

64

Acabei de descobrir que não deve haver nenhum caractere entre o back tick e a quebra de linha. Mesmo espaço em branco fará com que o comando não funcione.


10
Embora tecnicamente essa não seja a resposta para a pergunta, +1 porque isso é absolutamente essencial. Acabei de descobrir isso da maneira mais difícil e certamente evitarei o atraso no desenvolvimento futuro, sempre que possível.
precisa

4
Portanto, não existe uma maneira robusta de quebrar uma longa fila no Powershell. Não é de admirar que eu tenha visto esses scripts de PowerShell com 2 telas em todos os lugares. #ShakeMyHead
RayLuo

Eu também estava lutando com isso ... você pode inserir um comentário embutido antes do retorno para incluir um comentário, assim: Some-Command `-arg1 <# explica arg 1 #>` -arg2 <# explica arg 2 #>
joelsand 22/09

2
Urgh. Isso torna o código do PowerShell desnecessariamente difícil de postar na documentação ou em sites, por medo de que o comando seja lido errado por um humano se você estiver usando Shift + Enter ou analisado errado na linha de comando do ISE ao usar o back tick.
GuitarPicker # 26/17

Voto negativo devido à natureza do comentário (que não é uma resposta completa à pergunta original).
CodeBreaker

38

Na maioria das linguagens do tipo C, sou decidido a colocar meus aparelhos nos quais acho que eles tornam o código mais fácil de ler.

O analisador do PowerShell reconhece quando uma declaração claramente não está completa e olha para a próxima linha. Por exemplo, imagine um cmdlet que use um parâmetro opcional de bloco de script:

    Get-Foo {............}

se o bloco de scripts for muito longo, você pode escrever:

    Get-Foo
    {
        ...............
        ...............
        ...............
    }

Mas isso não vai funcionar: o analisador verá duas instruções. O primeiro é Get-Fooe o segundo é um bloco de script. Em vez disso, escrevo:

    Get-Foo {
        ...............
        ...............
        ...............
    }

Eu poderia usar o caractere de continuação de linha (`), mas isso torna o código difícil de ler e convida a erros.

Como esse caso exige que a chave aberta esteja na linha anterior, sigo esse padrão em todos os lugares:

    se (condição) {
        .....
    }

Observe que as ifinstruções exigem um bloco de script na gramática do idioma; portanto, o analisador procurará na próxima linha o bloco de scripts, mas, por consistência, mantenho o colchete aberto na mesma linha.

De maneira semelhante, no caso de tubulações longas, quebro após o caractere de tubulação ( |):

    $ project.Items | 
        ? {$ _. Key -eq "ProjectFile"} |
        % {$ _. Valor} | 
        % {$ _. EvaluatedInclude} |
        % {
            .........
        }

como faz ife foreache trytrabalho, então? eles permitem que blocos de script na linha seguinte ... Isso significa que ele MUT ser possível
Nacht - Reintegrar Monica

@Nacht: De memória enferrujada: as instruções que requerem um bloco de script, de acordo com a gramática do idioma, analisam uma nova linha para encontrar uma. Alguém pode confirmar?
Jay Bazuzi

2
@ Nacht: "Mas isso não vai funcionar" estava se referindo a situações em que os parâmetros adicionais são opcionais, como na maioria dos casos.
Jay Bazuzi

1
ah eu entendo o que você quer dizer agora. então "if" e "foreach" não são realmente cmdlets - eles fazem parte da gramática, forçando-a a olhar para a próxima linha. então não há como permitir que uma função definida pelo usuário leia um bloco de script da próxima linha? Suponho que sua resposta acima responda exatamente a essa pergunta.
Nacht - Reinstate Monica

29

Para expandir a resposta de cristobalito :

Suponho que você esteja falando na linha de comando - se estiver em um script, uma nova linha> atua como um delimitador de comando.

Na linha de comando, use um ponto-e-vírgula ';'

Por exemplo:

Assine um script do PowerShell na linha de comando. Sem quebras de linha.

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}

10
Não é a resposta para a pergunta, mas sua resposta respondeu à minha pergunta. :)
Frederik

1
Isso é interessante, mas é o oposto do que o OP estava perguntando. O OP queria dividir um único comando em várias linhas; você explicou como combinar vários comandos em uma linha.
Daniel Yankowsky

17

No PowerShell e no PowerShell ISE, também é possível usar Shift+ Enterno final de cada linha para edição de várias linhas (em vez do backtick padrão `).


2
Essa é uma ótima dica para editar seqüências de caracteres de várias linhas aqui, que são horríveis de editar se você não souber o SHIFT-ENTERtruque.
dpw

1
Acredito que esse seja o caso na versão do console do PowerShell apenas ao usar o PSReadLinemódulo ou equivalente. Nas funções de entrada padrão do console do Windows Entere Shift+Entersão funcionalmente equivalentes.
Bill_Stewart

@ Bill_Stewart true, funciona no console do ISE sem PSReadline, mas não no host do console.
Briantist

2
Para esclarecer: 1) O PSReadlinemódulo funciona no hospedeiro consola única (não ISE). 2) Shift+Enterfunciona no host do console apenas ao usar PSReadline. 3) Shift+Entersempre trabalhou no ISE. 4) Se usar o host do console sem PSReadline, Shift+Enteré funcionalmente equivalente a pressionar Enter.
Bill_Stewart

2
esta é a resposta certa, a que é aceita e tem 400 votos positivos é muito confusa e inútil !!
FLICKER

4

Se você estiver tentando separar seqüências de caracteres em várias linhas, poderá usar o "+". Por exemplo:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Será parecido com:

$header = "Make,ComputerName,Model,Windows Version"

2

Suponho que você esteja falando na linha de comando - se estiver em um script, uma nova linha atuará como um delimitador de comando.

Na linha de comando, use um ponto-e-vírgula ';'


1
  1. Use um ponto e vírgula ;para separar o comando
  2. Substitua a barra invertida dupla \\em qualquer barra invertida \.
  3. Use "'para passar um endereço seguro para alternar comandos como "'PATH'".

Este comando ps1 instala o certificado locale pfx.

powershell -Command "$pfxPassword = ConvertTo-SecureString -String "12345678" -Force -AsPlainText ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\My -Password $pfxPassword ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\Root -Password $pfxPassword"


0
$scriptBlock = [Scriptblock]::Create(@'
  echo 'before'
  ipconfig /all
  echo 'after'
'@)

Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

a fonte
não usa aspas



0

Basta adicionar uma caixa de canto aqui. Isso pode economizar 5 minutos. Se você usar uma cadeia de ações, precisará colocar "." no final da linha, deixe um espaço seguido pelo "` "(backtick). Descobri isso da maneira mais difícil.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.