Uso de ^ como metacaractere de concha

19

Escrevi hoje um pequeno script que continha

grep -q ^local0 /etc/syslog.conf

Durante a revisão, um colega de trabalho sugeriu que ^local0fosse citado porque ^significa "tubo" na casca de Bourne. Surpreso com essa afirmação, tentei rastrear qualquer referência que mencionasse isso. Nada que eu encontrei na internet sugeria que isso era um problema.

No entanto, verifica-se que a implementação de bsh(que afirma ser o shell Bourne) no AIX 7 realmente tem esse comportamento:

> bsh
$ ls ^ wc
      23      23     183
$ ls | wc
      23      23     183

Nenhuma das outras implementações do "shell Bourne" que tentei se comportar dessa maneira (ou seja, ^não é considerada um metacaractere do shell). Eu tentei shno CentOS (que é realmente o bash) e shno FreeBSD (o que não é o bash). Não tenho muitos outros sistemas para tentar.

Esse comportamento é esperado? Quais conchas consideram ^um metacaractere de tubo?

Greg Hewgill
fonte
1
Eu sei que esse ^é um caractere de negação no zsh e também no espaço regex. Como um comentário separado, geralmente é aconselhável usar aspas simples na expressão grep para portabilidade entre shells.
Mkc
O shell bourne tinha muitos comportamentos estranhos que ainda vemos contornos no código do shell moderno, por exemplo [ x"$foo" = x"bar" ].
Jordanm # 9/13
bshnão é o Bourne Shell. O nome foi abusado apenas para o Bourne Shell no AIX. bshé um shell introduzido por mim em 1984 na H.Berhold AG no UNOS (o primeiro clone do UNIX). Note-se que AIX não era inexistente em 1984.
Schily

Respostas:

21

O ^personagem como sinônimo |remonta ao shell Thompson . Eles foram introduzidos ao mesmo tempo no Unix v4 e são mencionados juntos na página do manual . Sven Mascheck menciona que ^"provavelmente foi introduzido por razões de conveniência nos primeiros terminais somente em maiúsculas", em que a digitação |foi "um tanto dolorosa" .

O shell Thompson já se foi há muito tempo, mas seu sucessor, o shell Bourne, manteve a mesma sintaxe (embora sua página de manual apenas mencione |).

Os reservatórios sucessores, como ash, bash e ksh, entendem apenas |como o caractere de pipe. Você não encontrará um shell Bourne real em variantes unix de código aberto, pois por um longo tempo não houve liberação de código aberto do shell Bourne. (Acho que o OpenSolaris incluiu um, mas não foi adotado em nenhum outro lugar, pois naquela época estava obsoleto por implementações mais recentes).

A especificação Single Unix não menciona ^como um caractere especial, o que significa efetivamente que os shells POSIX devem interpretá-lo literalmente¹. Acho que nunca houve uma variante totalmente compatível com POSIX do shell Bourne (apenas implementações independentes).

^é especial no zsh quando a opção extendedglobestá ativada, mas não no modo de compatibilidade sh. Em seu modo padrão, ele se desvia do POSIX de várias maneiras.

Eu recomendo citar ^em uma expressão regular de qualquer maneira para maior clareza. Cite a expressão regular em um script, independentemente dos caracteres que aparecem nele.

¹ Exceto como o primeiro caractere de uma expressão de colchete em um padrão curinga, onde !é o caractere de negação padrão, mas as implementações também podem interpretar ^da mesma maneira.

Gilles 'SO- parar de ser mau'
fonte
Obrigado, todo esse tópico do TUHS de 2003 foi esclarecedor.
Greg Hewgill,
Para completar, você pode mencionar que ^é especial fishonde é um operador de redirecionamento, rc/ esonde é um operador de concatenação ou csh / tcsh / bash / zsh para expansão do histórico quando é o primeiro caractere da linha de comando.
Stéphane Chazelas
3

Sim, o OpenSolaris inclui a fonte Bourne Shell, mas essa fonte não é portátil.

Uma versão mantida e altamente portátil da fonte Bourne Shell pode ser encontrada aqui nos schily-*.tar.bz2arquivos.

Aqui está a parte relacionada da fonte em cmd.c:

/* 
* ^ is a relic from the days of UPPER CASE ONLY tty model 33s 
*/ 
if ((t = item(TRUE)) != 0 && (wdval == '^' || wdval == '|')) 

Veja bem, isso não está relacionado a um shell específico (por exemplo, o shell Thompson), mas ao fato de que, na década de 1970, ainda havia apenas maiúsculas terminais ao redor.

esperto
fonte