2010-07-14 12:51:58 +0000 2010-07-14 12:51:58 +0000
32
32

bash: como passar argumentos de linha de comando contendo caracteres especiais

Eu próprio escrevi um programa de linux program que precisa de uma expressão regular como entrada.

Quero chamar o programa na shell bash e passar essa expressão regular como argumento de linha de comando para o programa (há também outros argumentos de linha de comando). Uma expressão regular típica parece

[abc]\_[x|y]

Infelizmente os caracteres [, ], e | são caracteres especiais em bash. Assim, chamar

program [abc]\_[x|y] anotheragument

não funciona. Existe alguma forma de passar a expressão usando algum tipo de caracteres de fuga ou aspas, etc.?

(A chamada program "[abc]\_[x|y] anotheragument" também não funciona, porque interpreta os dois argumentos como um só).

Respostas (8)

29
29
29
2010-07-14 12:59:46 +0000

Pode escapar a cada símbolo especial com uma barra invertida (como em \[abc\]_\[x\|y\]) ou 2. Duplicar o argumento inteiro (como em "[abc]_[x|y]").

EDIT: Como alguns salientaram, a dobleqouting não impede a expansão de variáveis nem a substituição de comandos. Portanto, se o seu regex contém algo que pode ser interpretado por bash como um desses, use aspas simples em vez disso.

28
28
28
2011-10-21 12:19:50 +0000

Utilizar citações simples. As citações simples garantem que nenhum dos caracteres seja interpretado.

$ printf %s 'spaces are not interpreted away
neither are new lines
nor variable names $TESTING
nor square brackets [TESTING]
nor pipe characters or redirection symbols | > <
nor the semicolon ;
nor backslashes \a \b \c \
the only thing that does not work is the single quote itself
'

Existem duas soluções se for necessário incorporar uma única citação:

$ printf '%s\n' '[Don'"'"'t worry, be happy!]'
[Don't worry, be happy!]
$ printf '%s\n' '[Don''t worry, be happy!]'
[Don't worry, be happy!]
6
6
6
2010-07-15 06:09:18 +0000

Por man bash

Existem três mecanismos de citação: o escape character, aspas simples, e aspas duplas.

& > Uma barra invertida não cotada ( * ) é o escape character. Preserva o valor literal do próximo carácter que se segue, com a excepção de .

& > O fecho de caracteres entre aspas simples preserva o valor literal de cada carácter dentro das aspas. Uma única aspas pode não ocorrer entre aspas simples, mesmo quando precedida por uma barra invertida.

& > O fecho de caracteres entre aspas duplas preserva o valor literal de todos os caracteres dentro das aspas, à excepção de $* , ` , ** , and, when history expansion is enabled, **!. The characters $ and ` mantêm o seu significado especial dentro de aspas duplas. A barra invertida mantém o seu significado especial apenas quando seguida por um dos seguintes caracteres: $* , `* , ”** , ***** , ou . Uma citação dupla pode ser citada dentro de aspas duplas, precedendo-a com uma barra invertida. Se activada, a expansão do histórico será executada a menos que um *!** que apareça entre aspas duplas seja evitado usando uma barra invertida. A barra invertida que precede o ! não é removida.

Os parâmetros especiais * e @ têm um significado especial quando entre aspas duplas (ver PARAMETERS* abaixo).

& > As palavras do formulário $‘ string são tratadas especialmente. A palavra expande-se para string, com caracteres em forma de barra invertida substituídos como especificado pela norma ANSI C. As sequências de fuga por contrabarra, se presentes, são descodificadas como se segue:

**\a** alert (bell) **\b** backspace **\e**** \E **an escape character** \f **form feed** \n **new line** \r **carriage return** \t **horizontal tab** \v **vertical tab** \ **backslash**  
& > 
O resultado expandido é citado individualmente, como se o sinal do dólar não tivesse estado presente. 


& > Uma cadeia de caracteres duplamente cotada precedida por um sinal de dólar ( **$"** _string_ **"** ) fará com que a cadeia seja traduzida de acordo com o local actual. Se o locale actual for **C*** ou **POSIX** , o sinal de dólar é ignorado. Se a cadeia de caracteres for traduzida e substituída, a substituição é duplamente cotada. **single quote** \" **double quote** \**_nnn_ the eight-bit character whose value is the octal value _nnn_ (one to three digits)**\x**_HH_ the eight-bit character whose value is the hexadecimal value _HH_ (one or two hex digits)**\u**_HHHH_ the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value _HHHH_ (one to four hex digits)**\U**_HHHHHHHH_ the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value _HHHHHHHH_ (one to eight hex digits)**\c**_x_ a control-_x_ character

& > O resultado expandido é citado individualmente, como se o sinal do dólar não tivesse estado presente.

& > Uma cadeia de caracteres duplamente cotada precedida por um sinal de dólar ( $“ string ) fará com que a cadeia seja traduzida de acordo com o local actual. Se o locale actual for C* ou POSIX , o sinal de dólar é ignorado. Se a cadeia de caracteres for traduzida e substituída, a substituição é duplamente cotada.

2
2
2
2010-07-15 02:11:13 +0000

Embora possa não ser útil como um regex, algumas sequências de caracteres podem ser interpretadas como nomes de variáveis Bash. Para evitar que isto aconteça e evitar que se expandam, usar aspas simples em vez de aspas duplas:

program '[abc]_[x|y]' anotherargument

Citar cada argumento separadamente (se necessitarem de citações) para que sejam interpretados como argumentos independentes. Também se podem utilizar arrays em alguns casos:

param_array=('[abc]_[x|y]' anotherargument) # create an array
param_array+=(yetanother) # append another element to the array
program "${param_array[@]}" # use the array elements as arguments to program
2
2
2
2010-07-14 12:57:29 +0000

Pode usar uma barra invertida ( `Pode usar uma barra invertida ( ) em frente de caracteres especiais para os escapar assim:

john@awesome:~ # echo 0x1& &
1
1
1
2010-07-14 12:56:05 +0000
program "[abc]_[x|y]"
program "[abc]_[x|y]" anotherargument
0
0
0
2010-07-15 07:18:57 +0000

De onde vem o padrão? É fixo ou de um utilizador? É o utilizador que está a invocar o guião no sistema local, ou alguém remoto?

Utiliza citações para embrulhar dados para evitar que a concha os interprete. Há duas opções:

  1. aspas duplas, que ainda permitem alguma interpretação ($expandir e backticks)
  2. As aspas simples, que passam tudo literalmente

Porque $ é um carácter válido em regexps (fim de linha/buffer), provavelmente quererá usar aspas simples para manter a regexp, a menos que esteja a armazenar numa variável. Se estiver a recolher dados arbitrários de alguém não confiável, terá de substituir ' por '"'"' e depois embrulhar em aspas simples.

Note que [abc]_[x|y] parece que quer corresponder x ou y, enquanto que na realidade corresponde a um dos três caracteres xy|. Os parênteses rectos correspondem aos caracteres dentro e apenas - para intervalos e um ^ no início para negação. Portanto, [abc]_(x|y) pode ser o que quis dizer, e os parênteses são os caracteres que são especiais para a concha. Os parênteses quadrados são não especiais para shell, apenas parece que são. Os parênteses quadrados duplos [[...]] são especiais.

0
0
0
2010-07-14 12:57:13 +0000

Escapar-lhes deve funcionar bem:

programm \[abc\]_\[x\|y\]