Espaços próximos a tubulações

17

Eu já vi history | grep blahe history |grep blah; e history|grep blahtambém funciona, embora ninguém pareça usá-lo.

Existe algum significado nos espaços (por exemplo, canalizar para / de comandos diferentes requer uso diferente de espaços) ou é sempre arbitrário?

EmmaV
fonte
13
Legibilidade, principalmente.
Jasonwryan 01/03
1
|pipe ou ;ponto- e- vírgula são usados ​​pela maioria dos shell (bash, ksh, tcsh) como separador de comandos. quando não estiver entre aspas, os espaços em branco antes e depois não são relevantes.
Archemar

Respostas:

24

bashdefine vários metacaracteres . De man bash:

metacaractere
Um caractere que, quando não está entre aspas, separa as palavras. Um dos seguintes:
| &; () <> guia de espaço

Como os metacaracteres separam as palavras, não importa se elas estão cercadas por espaços. O símbolo do tubo,, |é um metacaractere e, portanto, como você notou, não precisa de espaços ao seu redor.

Note-se que [, ], {, }, e =são não metacaracteres. Seu significado, por outro lado, depende fortemente de estar cercado por espaços em branco.

Exemplos de quando os espaços são e não são necessários

Como você notou, não importa se |é cercado por espaços. Vamos considerar alguns exemplos que geralmente confundem os usuários do bash. Considerar:

$ (date)
Sun Mar  1 12:47:07 PST 2015

Os parâmetros acima forçam o datecomando a ser executado em um subshell. Como (e )são metacaracteres, não são necessários espaços. Por contraste:

$ {date}
bash: {date}: command not found

Como {e não} são metacaracteres, o shell trata como uma palavra. Em vez de procurar o comando, ele procura um comando chamado . Como não encontra um, ocorre um erro.{date}date{date}

Outro problema comum é o testcomando. O seguinte funciona com sucesso:

$ [ abc ] && echo Yes
Yes

Remova os espaços e ocorre um erro:

$ [abc] && echo Yes
bash: [abc]: command not found

Como [e não] são metacaracteres, o shell trata como uma única palavra e o resultado, como no exemplo, é um erro.[.bashrc]date

As instruções de atribuição também são sensíveis aos espaços. A seguinte atribuição foi bem-sucedida:

$ v=date
$ echo $v
date

Adicione um espaço e a atribuição falhará:

$ v= date
Sun Mar  1 12:55:05 PST 2015

Acima, o shell temporariamente define vcomo vazio e, em seguida, executa o datecomando.

Adicionar um espaço antes =também causa uma falha, mas por um motivo diferente:

$ v =date
bash: v: command not found

Aqui, o shell tenta executar o comando vcom o argumento =date. O erro ocorre porque não encontrou nenhum comando nomeado v.

John1024
fonte
1
Recentemente, fui vítima da declaração de atribuição. Eu tinha espaços antes e depois do =. Demorou um pouco para depurar.
topher
3

Os tubos permitem que você use a saída de um programa como entrada de outro ...

Quanto aos espaços, é apenas uma questão de legibilidade / preferência do pessoal, como @jasonwryan mencionado.

Uma barra de espaço antes e depois de "|" é a norma ....

Você também pode usá-lo com a coluna -t, não apenas para tornar seu liner elegante, mas também para a sua saída.

lnydex99uhc:depot_r user$ lsof | grep my | column -t
Microsoft  290  user  txt  REG  1,4  9515016  170972    /Library/Fonts/PCmyoungjo.ttf
bash       359  user  cwd  DIR  1,4  714      12246074  /Users/zatef/hw2/base/active/myapp
zee
fonte
2

Há um caso em que pode ser útil não usar espaços. Se você não estiver usando um layout norte-americano, poderá ser forçado a usar algumas combinações, como AltShiftLinserir um tubo. Embora isso não seja um problema em si, uma conseqüência é que às vezes você também insere caracteres não imprimíveis antes ou depois desse caractere. Por exemplo, em um teclado francês do Macbook Pro, tenho que usar AltShiftLpara inserir |. Ao digitar rapidamente, você pode digitar acidentalmente o seguinte: AltShift( L, Space)

$ sudo dmesg | tail
zsh: command not found:  tail

echo "sudo dmesg | tail" | od -a
0000000    s   u   d   o  sp   d   m   e   s   g  sp   |         t   a
0000020    i   l  nl

Se você não está ciente de que AltShiftSpaceinsere um espaço diferente (o espaço sem quebra ( U + 00A0 )), o seguinte erro pode ser difícil de entender:zsh: command not found:  tail

alecail
fonte
1

O único significado dos espaços neste caso é a estética.
Ou, em outras palavras, útil para tornar os comandos mais legíveis para um humano.

asoundmove
fonte