Uso de barra invertida em comandos diferentes

5

Eu tenho tentado entender melhor como a barra invertida é usada em certos comandos. Eu entendo seu uso para escapar caracteres especiais (como echo 'that'\''s no moon' ), mas a saída de outros comandos é um pouco confusa. Por exemplo:

rpm-qa rpmname\*

grep '\s/tmp' /etc/fstab

Alguém por favor pode dividir isso para mim? Também curioso sobre quaisquer outros usos que você possa conhecer. Obrigada!

    
por user217282 21.02.2017 / 20:40

4 respostas

2

A barra invertida costuma ser usada para dizer "faça o próximo caractere representar a si mesmo em vez de dar um significado especial". Dizemos que a barra invertida cita o próximo caractere. Esse significado está presente em muitas linguagens de programação, incluindo a sintaxe do shell. Por exemplo, em rpm-qa rpmname\* , a barra invertida faz com que o caractere * seja passado no argumento para o comando rpm-qa . Em contraste, rpm-qa rpmname* substitui rpmname* pela lista de nomes de arquivos no diretório atual, começando com rpmname . (Se não houver nenhum arquivo correspondente, o bash deixa rpmname* sozinho; o zsh, por padrão, reclama que não há correspondências.)

O shell oferece outra maneira de interpretar um caractere literalmente, ou seja, torná-lo autônomo em vez de ser interpretado de alguma maneira especial. Isso é citar, o que cancela o significado especial de toda uma sequência de caracteres. Existem dois tipos de aspas: aspas simples ' fazem cada caractere representar a si próprio até a próxima aspa simples, enquanto as aspas duplas " conservam um significado especial para alguns caracteres ( " , $ , \ e ' ). Em echo 'that'\''s no moon' , o comando echo recebe um único argumento, que é a concatenação de that (escrita com uma cadeia literal, não que houvesse qualquer caractere com um significado especial nesse caso específico), ' ( a aspas simples invertidas cancela o significado especial dessa aspa simples, então isso se expande para um caractere de aspas simples) e s no moon (os espaços perdem seu significado especial, pois estão entre aspas: em vez de separar argumentos, eles são parte do argumento).

No shell, quando a barra invertida tem um significado especial, geralmente é para citar o próximo caractere. Mas:

  • Dentro de aspas simples, a barra invertida não tem significado especial.
  • Dentro de aspas duplas, a barra invertida cita apenas o caractere seguinte, se for um dos "$\' . Caso contrário, tanto a contrabarra quanto o caractere seguinte são interpretados literalmente, por exemplo "\a" é a string de dois caracteres \a .
  • Dentro de literais de citação única com dolar, a contrabarra tem um significado diferente, semelhante ao que existe em C . Uma barra invertida seguida por dígitos octal ou por certas letras fornece maneiras alternativas de inserir caracteres, o que é útil para caracteres não imprimíveis. Por exemplo, \n é um N minúsculo, "\n" é uma barra invertida + n, mas $'\n' é um caractere de nova linha.

Em grep '\s/tmp' /etc/fstab , as aspas simples fazem com que grep receba o argumento \s/tmp . Este argumento é uma expressão regular . Existem muitas variantes de sintaxe para expressões regulares, mas a maioria é baseada em um dos dois padrões: POSIX expressões regulares básicas (BRE) e regulares regulares estendidos expressões (ERE) . ERE segue a convenção generalizada de que a barra invertida seguida por qualquer outra coisa que não uma letra ou um dígito cita o seguinte caractere. Mas, por razões históricas, no BRE, uma barra invertida pode, às vezes, tornar o próximo caractere especial quando, de outro modo, não seria. Nesse caso, \s é uma extensão grep do GNU para a sintaxe básica de regex, disponível tanto com BRE quanto com ERE, ou seja, um caractere de espaço em branco. Assim, grep '\s/tmp' /etc/fstab lista as linhas em /etc/fstab que contêm /tmp precedidas por um espaço ou tabulação.

    
por 23.02.2017 / 02:28
1

Estou assumindo que você está usando o bash ou algo assim.

Antes de mais nada, você precisa entender como o bash está avaliando sua entrada. Existem muitos caracteres especiais que você pode usar no bash. Alguns deles são, por exemplo, * ; ~ $

Quando você insere sua entrada, o bash tentará substituir todos os caracteres que deveriam estar. Por exemplo, variáveis que começam com um sinal $ . O * será substituído por todos os arquivos / diretórios presentes no diretório em que você está atualmente (Determine com pwd ).

Se a etapa de substituição estiver concluída, o bash finalmente executará (com um fork() ) o programa que você especificou.

O \ diz ao bash para ignorar o caractere especial dado: \*

    
por 21.02.2017 / 20:54
1

Você está certo, há uma convenção comum de que a barra invertida é usada para caracteres de escape, ou o dito personagem tem um significado especial e você quer que ele seja literal:

# echo 'It\'s a string!'

No exemplo acima, o apóstrofo é usado para delimitar uma string literal, mas como você precisa de um apóstrofo dentro da string, você deve escapar dela.

O outro caso é o oposto, quando você precisa de um caractere "normal" para ter algum significado especial:

# grep '\s/tmp' /etc/fstab

No exemplo acima, a barra invertida informa ao grep que s tem um significado especial e não é um literal s (é um espaço em branco RegEx: espaço, tabulação, nova linha, retorno de carro, tabulação vertical)

Em outras palavras, quando um personagem tem 2 significados possíveis, você o escapa para que seja o significado secundário.

Editar:

Para o seu primeiro exemplo:

rpm-qa rpmname\*

Aqui * tem um significado especial (qualquer coisa que comece com 'rpmname'), mas para evitar que o shell tente expandi-lo, o comando rpm obtém o literal * e pode processá-lo de acordo.

Isso diminui quantas vezes as strings forem interpretadas e podem ser uma verdadeira luta quando a string é passada por vários comandos.

    
por 21.02.2017 / 20:51
1

O \ é usado tanto para caracteres especiais quanto para expressões regulares.

Seu comando rpm está escapando de * , que, nesse caso, é funcionalmente o mesmo que não escapar dele. O RPM sabe que * é um caractere de pacote inválido, então ele o interpreta mesmo se você escapar dele. Escapar de um caractere especial é mais usado em situações como o tratamento de nomes de arquivos com caracteres não alfanuméricos.

Assumindo dois arquivos, um chamado 'foo-biz-bar' e outro 'foo * bar', e queremos apenas ver 'foo * bar'. O primeiro resultado abaixo ocorre porque um * sem escape é um caractere curinga de blob.

$ ls foo*bar
foo*bar foo-biz-bar
$ ls foo\*bar
foo*baz

O \s no exemplo grep é uma expressão regular que significa 'qualquer espaço em branco', significando tabulações e espaços.

Leitura adicional

É difícil obter listas exaustivas de expressões regulares on-line, mas você pode começar aqui .

Um livro que me ajudou significativamente foi o 'Unix Shells by Example'. O uso extenso de sed , grep e awk também foi coberto.

    
por 21.02.2017 / 21:15