Bash's declara -p HISTIGNORE faz parar o bash! Por quê?

3

Executando o seguinte código no GNU bash, Versão 4.2.45 (1) -release (x86_64-redhat-linux-gnu), Fedora 19 ...

shopt -s extglob
export HISTIGNORE="!(+(!([[\:space\:]]))+([[\:space\:]])+(!([[\:space\:]])))"
declare -p HISTIGNORE

... leva o bash a um ponto final. Ele não imprime um prompt de comando daqui em diante. Por que isso?

Antecedentes:

Tudo o que quero dizer bash é ignorar qualquer comando simples, ou seja, uma palavra. O Bash não deve se lembrar de linhas de comando como cd , pwd , history , etc. Minha definição original da variável HISTIGNORE ficou assim:

export HISTIGNORE="!(+(!([[:space:]]))+([[:space:]])+(!([[:space:]])))"

Eu adicionei um caractere de barra invertida \ antes de cada caractere de dois pontos : porque, de acordo com as páginas de informações bash , o último separa cada globo de concha (estendido), ou seja, padrão de outro. Sem escapar do padrão único, não tem nenhum efeito e um simples comando ainda faz parte do histórico.

    
por Tim Friske 11.01.2014 / 23:44

2 respostas

4

Seu padrão é muito complexo. Negar uma expressão regular tende a ter um comportamento exponencial no tamanho da expressão regular, e você tem uma negação dentro de uma negação, o que poderia levar a uma exponencial dupla. Ulp.

No entanto, um congelamento tão longo não é desejável. Eu observo o mesmo comportamento no Debian com o bash 4.2.37 no Debian, então relate isso como um bug no upstream. Mas esteja preparado para ser informado de que seria muito trabalho para muito pouco benefício fazer esse caso funcionar.

Nesse meio tempo, duvido que o padrão realmente faça o que você quer. Há uma maneira muito mais simples de ignorar comandos de palavra única:

HISTIGNORE='+([a-z])'

Ajuste isso se você quiser ignorar até mesmo comandos raros contendo outros caracteres em seu nome ou se você quiser ignorar o espaço em branco. Por exemplo:

HISTIGNORE=$'*([\t ])+([-%+,./0-9\:@A-Z_a-z])*([\t ])'

Observe que você não precisa exportar HISTIGNORE . Esta é uma variável interna bash, não uma variável de ambiente.

    
por 12.01.2014 / 00:13
1

Nesse meio tempo recebi a seguinte resposta de Chet Ramey do [email protected]:

  1. O matcher explode e vai exponencial quando as barras invertidas estão em lá. Eu não investiguei por quê.

  2. Você não precisa das barras invertidas; os dois pontos fazem parte dos padrões. o ignore o analisador de padrões entende a sintaxe do padrão, então os dois pontos no as expressões de colchetes não dividem o valor.

  3. O valor HISTIGNORE sem as barras invertidas parece funcionar usando bash-4.2.45: comandos simples de palavra única não são adicionados à lista de histórico.

por 12.01.2014 / 15:05