Por que a substituição do histórico do bash ainda está ativada por padrão? [fechadas]

17

Alguém sabe por que o bash ainda tem a substituição do histórico ativada por padrão? O meu .bashrcfoi incluído set +Hpor muitos anos, mas algumas outras pessoas ainda estão sendo mordidas por esse recurso.

Dado que praticamente todo mundo está usando terminais com recursos de copiar e colar e o bash compilado com substituição de readlinebiblioteca e histórico é ativado por padrão apenas em shells interativos, existe realmente alguma razão para ter esse recurso? Nenhum dos scripts existentes seria quebrado, mesmo que estivesse desativado por padrão para todos os shells.

Tente isso se você não souber por que a substituição do histórico está quebrada:

$ set +H # disable feature history substitution
$ echo "WTF???!?!!?"
WTF???!?!!?
$ set -H # enable feature history substitution
$ echo "WTF???!?!!?"
echo WTF???echo WTF???!?!!?
WTF???echo WTF???!?!!?

(Claramente, o recurso apresenta grandes problemas se estiver desativado por padrão para todos os scripts e existe um recurso para verificar os resultados antes de executar:. shopt -s histverify)

Veja também:

Mikko Rantalainen
fonte
16
Você parece pensar que as pessoas não usam a substituição da história. Eu uso todos os dias. I encontrar a mais rápida de seguir ls -l foo/bar/baz/weeble.cppcom less !$a recordação do comando e editá-lo.
Martin Bonner apoia Monica
2
@MartinBonner Para que você possa habilitá-lo. A questão é por que ela está ativada por padrão , e não por que ela ainda existe.
Barmar
5
@ Barmar: Claro. Mas meu objetivo era desafiar a suposição de que a questão é baseada.
Martin Bonner apoia Monica
5
Se seguirmos seu raciocínio, qualquer coisa que exija escape ou citação deverá ser desativada por padrão. Por que eu preciso escapar ou citar um URL que contenha &? Por que eu preciso escapar ou citar um nome de arquivo que contém um ?? Existem UIs para pessoas que pensam que isso é um problema.
jcaron
3
Eu uso !$várias vezes ao dia, e !!muitas vezes também. Devo admitir que não uso tanto outras substituições do histórico, mas ficaria infeliz se o comportamento padrão do shell que uso há anos mudasse repentinamente.
jcaron

Respostas:

32

Se você já está familiarizado com bash , não é muito provável que lidar com padrões de substituição de histórico o incomode do que lidar com outros caracteres especiais para esse shell. No entanto, se alguém não estiver familiarizado com o shell ou simplesmente nunca usar seus recursos de substituição de histórico, obviamente será uma surpresa quando as seqüências aparentemente inócuas, sem aspas ou com aspas duplas, o ativam.

Em um shell interativo com as substituições de histórico ativadas, o !personagem é especial da mesma maneira que o $personagem é especial, ou seja, em todos os lugares, a menos que escape com\ ou em cadeias de citação simples.

Ao contrário de $substituições, as substituições de histórico não se expandem nos documentos aqui e, como são orientadas por linhas, ocorrerão adicionalmente nas linhas em que a substituição se enquadra em um contexto sem aspas ou em um contexto de aspas duplas (nessa linha, quando digitalizada separadamente) . Veja este relatório de bug para mais informações .

A substituição do histórico é desativada em shells (scripts) não interativos porque o recurso de histórico de comandos do shell não é necessário lá, não porque o recurso tenha "problemas importantes". Em um script, salvar todos os comandos para $HISTFILEnão faz sentido, e a substituição do histórico da mesma forma não é algo em que você deseja confiar em um script.

Se deve ou não ser ativado por padrão ou não em shells interativos, pode ser debatido (embora eu não esteja totalmente convencido de que um debate aqui seja importante para os bashdesenvolvedores). Você parece pensar que a maioriabash usuários está tendo problemas com as expansões do histórico, mas nenhum de vocês e eu sabemos como é comum usá-las.

Os shells Unix permitem modificar o comportamento do shell para atender às necessidades e gostos pessoais. Se você deseja desativar as substituições do histórico de todos os seus shells interativos, continue fazendo o que está fazendo set +Hno seu ~/.bashrcarquivo ou faça lobby com os bashdesenvolvedores para alterar o padrão (que, acredito, perturbaria e confundiria mais pessoas do que ajudaria )

Kusalananda
fonte
2
@MikkoRantalainen Parece que a substituição do histórico não é algo que a maioria dos bashusuários está usando. Acho que nenhum de nós sabe o quão comum é. Eu sugiro que, se você se sentir bem com isso, envie uma solicitação de recurso / bug à bashlista de discussão. Veja savannah.gnu.org/mail/?group=bash
Kusalananda
8
Certo. O problema não é realmente sobre a substituição da história, mas sobre o fato de que aspas duplas no Bash não são realmente aspas no sentido em que outros idiomas usam o termo, mas funcionam como um tipo especial de parênteses. @MikkoRantalainen, crie o hábito de colocar qualquer coisa que você não queira que o Bash interprete de maneira especial em aspas simples !
usar o seguinte código
5
@leftaroundabout Depende do que você entende por interpretação. A maioria das linguagens interpreta caracteres de controle em seqüências de caracteres para saída (mas concedidas, não da mesma maneira que no shell quando apenas embaralhando as seqüências). As regras de citação de Perl também funcionam como as do shell (interpolação variável). Como em qualquer linguagem de programação, ajuda se alguém conseguir se lembrar em qual linguagem está trabalhando atualmente.
Kusalananda
5
" meu argumento é que! é um personagem especial tão raramente usado " Eu diria que é o contrário ... !é tão raramente usado como um personagem normal que - ecoando os WTFs de lado - o número de pessoas que são pegas é superado pelo número de pessoas que ainda o usam para substituir a história.
TripeHound 9/04
3
-1 por desviar a culpa para citações impróprias. Como não! é especial para a maioria dos shells tipo Bourne, nem nos scripts, existem muitos caminhos pelos quais as pessoas podem razoavelmente aprender que expandirão o mas não o . Eu me familiarizei com o shell tipo Bourne , e meu primeiro encontro com a substituição da história foi eu ser mordido por ele quando estava tentando fazer uma linha rápida em um shell interativo. Pessoas com proficiência no uso portátil e de scripts de shells semelhantes a Bourne são frequentemente mordidas pelo menos uma vez ao usá-las . bash"$my_var some text!!"$my_var!!busybox ashbashbash
Mtraceur # 9/18
9

A substituição do histórico é útil. Considere por exemplo

% make-me-a-sandwich
make-me-a-sandwich: Permission denied
% sudo !!
Ok.
Johan Myréen
fonte
2
Então? Se você achar útil, poderá ativá-lo no seu .bashrc.
Barmar
3
xkcd.com/149
Walter Tross
3
@ Barmar e se você achar que não é útil, poderá desativá-lo. Engraçado como a simetria funciona.
precisa
3
@ Hobbs Se você não sabe que existe, como saberia desativá-lo?
Barmar
2
Esta resposta explica bem um dos motivos pelos quais o recurso é útil. Acho que o OP quer entender por que essa utilidade é suficiente para justificar esse comportamento, mesmo que o OP (e outros, como as pessoas que fazem várias perguntas relacionadas nessa troca de pilha) achem esse comportamento surpreendente / inesperado.
Mtraceur # 10/18
4

Inércia social / cultural.

Esta questão está no espaço de problemas de como os humanos trabalham, por isso vou responder desse ângulo, sem emitir nenhuma opinião sobre se o recurso deve ou não por padrão.

Para começar, certifique-se de entender o outro lado, considere que o aborrecimento que você sente por ter que sair do seu caminho para desativar o recurso é o aborrecimento que eles teriam sentir se tivessem que sair de seu caminho para ativar a característica.

Combine o que precede com o fato de que bash usuários usarem o recurso, sugestões de removê-lo ou desativá-lo por padrão são encontradas com resistência por parte das pessoas que já se sentem confortáveis ​​com o fato de estar lá por padrão.

Além disso, bashé o shell padrão para muitas pessoas (não apenas no sentido de logon padrão ou no shell do sistema, mas no sentido psicológico). Se o seu quadro de referência para citação de shell for bash, se esse for o shell que você aprendeu primeiro, o fato de que! ser um caractere especial do shell parecerá natural e automático para você (ou pelo menos, quando você o aprender pela primeira vez, será apenas parte de do jeito que o shell é, apenas uma peculiaridade para aceitar entre muitos).

E se você pensar bem, muitos bashusuários provavelmente encontrarão a sintaxe de substituição do histórico em um contexto positivo : eles leem sobre isso ou alguém mostra isso para eles e veem a possível utilidade disso quando aprendem pela primeira vez bash.

É apenas do mundo periférico de outras conchas do tipo Bourne que você seria mordido por !ser especial e, portanto, inclinado a vê-la negativamente: porque se você está acostumado a conchas onde nunca teve o recurso, então seu primeiro a exposição será quando você estragar tudo quando estiver tentando fazer algo com pressa.

TL; DR: a maioria dos usuários provavelmente não se importa muito com o que é o padrão , alguns usuários gostam do recurso e têm a grande vantagem de já ser assim, e não há pessoas o suficiente ativamente ativando contra o recurso para superar isso.

mtraceur
fonte
2
Não, não é só quando vem de outras conchas. Eu conheço esse recurso há anos bashe ainda sou mordido de surpresa, pois as aspas simples nem sempre funcionam por !causa da bashimplementação interrompida .
Philippos
@ Philippos Isso é aterrorizante (bem, não exatamente aterrorizante ... mas algum tipo de qualia negativo angustiante). Obrigado por apontar isso. Tentarei revisar esta resposta mais tarde para inserir seu ponto na minha resposta depois de pensar em uma boa maneira de integrá-la.
Mtraceur
2

Por que a substituição do histórico do bash ainda está ativada por padrão?

Como muitas pessoas o usam, e as pessoas que usam um shell bash interativo provavelmente devem conhecer as regras para evitar problemas e geralmente acharão que ajuda mais do que dói.

Meu .bashrc inclui o conjunto + H há muitos anos, mas algumas outras pessoas ainda estão sendo mordidas por esse recurso.

Portanto, é um recurso que você não usa, que não significa que a maioria dos usuários não o usa. Você pode solicitar que o padrão seja alterado, mas você deve observar A) a porção de pessoas que se importam e B) a proporção de pessoas que preferem isso do seu jeito. As pessoas que se importam e não gostam provavelmente já o desativaram. Mudá-lo ajudaria quando eles obtiverem uma conta em um novo computador. As pessoas que se importam e gostam disso precisam atualizar suas configurações em todos os computadores que usam e em todas as contas que obtiverem no futuro.

Dado que praticamente todo mundo está usando terminais com recursos de copiar e colar

Uma opção mais desajeitada na minha opinião ...

existe realmente alguma razão para ter esse recurso? Nenhum dos scripts existentes seria quebrado, mesmo que estivesse desativado por padrão para todos os shells.

Sim, as pessoas acham útil. Qual é a utilidade de ter um controle remoto, já que você costumava se levantar e mudar de canal?

(Claramente, o recurso apresenta grandes problemas se estiver desativado por padrão para todos os scripts e existe um recurso para verificar os resultados antes de executar: shopt -s histverify.)

O histórico não faz muito sentido nos scripts, mas, o mais importante, pode causar problemas de segurança. No seu caso, você pode evitar o problema usando aspas simples. Não me lembro de isso ter causado um problema para mim, então não sei como você pode dizer que ele tem "problemas importantes". Isso causou um problema real para você ou você ficou chateado por ter que definir seus padrões em um novo computador?

Não vejo como é diferente ter que escapar ou usar aspas simples se você realmente deseja obter algum dinheiro:

$ echo "Give me $50 or the cat gets it"
Give me $0 or the cat gets it
Jason Goemaat
fonte
2
Veja as perguntas relacionadas (coluna da direita); a maioria das perguntas está atingindo esse recurso por acidente e assume que o shell está quebrado. Eu, pessoalmente, aprendi sobre esse recurso há muito tempo, devido ao fato de ter usado acidentalmente a sequência de caracteres que causava erros de saída. Eu teria sido salvo por, shopt -s histverifymas isso não estava ativado por padrão. Além disso, descobrir a causa por si mesmo é bastante difícil, porque a mensagem de erro é enigmática ("evento não encontrado") e a sequência de caracteres que a aciona é difícil de pesquisar no Google.
Mikko Rantalainen
1
As pessoas são genuinamente mordidas por esse recurso, porque os recursos de sintaxe "universal" do shell, como $ser especial por dentro, "..."são uma das primeiras coisas que as pessoas aprendem sobre o shell, enquanto o fato de !ser especial por dentro "..."(mas apenas no modo interativo) é menos conhecido, geralmente não é ensinado como imediato / destacado e é bashespecífico. Além disso, os shell do tipo Bourne geralmente têm uma simetria entre o texto em um script e o texto no shell interativo, para que você possa copaste de um para o outro e funcione da mesma maneira - e esse recurso cria uma das únicas exceções.
Mtraceur # 10/18
1
Não vejo como é diferente ter que escapar ou usar aspas simples True para zsh, quando as aspas simples !sempre funcionam, mas não para bash, onde a implementação produz resultados inesperados . Você diz que devemos conhecer as regras , bem, você conhecia essa regra vinculada?
Philippos