Por que o Mac Terminal se lembra de dois comandos consecutivos quando são iguais?


9

Comecei a usar o Mac recentemente e antes de trabalhar no Ubuntu.

Suponha que eu execute esses comandos um por um no meu terminal:

python3 main.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py
python3 main2.py

Agora, suponha que eu queira executar python main.pynovamente, então clicarei na tecla para cima. Vou precisar clicar na tecla apenas duas vezes no Ubuntu, mas sete vezes no Mac.

Se dois comandos consecutivos forem iguais, o terminal deve lembrar apenas um comando em vez de lembrar dois comandos diferentes.

Como posso fazer isso acontecer no macOS?


6
Apenas para pedante, não é realmente o terminal mac que está fazendo isso. É bash, seu shell rodando no terminal. Existem muitos shells e é possível e comum substituir o shell padrão por algo como zshe ainda mais personalizar o zsh com vários scripts.
Gman #

Respostas:


13

Você precisa adicionar a variável de ambiente HISTCONTROL ao seu .bash_profile. No seu, .bash_profileadicione a seguinte linha:

export HISTCONTROL=ignoreboth:erasedups

Feche e reinicie sua sessão do bash e os dupes devem desaparecer. Como alternativa, você pode simplesmente executar a mesma linha e ela entrará em vigor nessa sessão (use-a para testá-la).


Na páginabash do manual para (no Terminal):

HISTCONTROL
Uma lista de valores separados por dois pontos que controla como os comandos são salvos na lista de histórico. Se a lista de valores incluir ignorespace , as linhas que começam com um caractere de espaço não serão salvas na lista de histórico. Um valor de ignoredups faz com que as linhas correspondentes à entrada do histórico anterior não sejam salvas. Um valor de ignoreboth é uma abreviação de ignorespace e ignoredups . Um valor de apagados faz com que todas as linhas anteriores correspondentes à linha atual sejam removidas da lista de histórico antes que a linha seja salva. Qualquer valor que não esteja na lista acima é ignorado. Se HISTCONTROLestá desativado ou não inclui um valor válido, todas as linhas lidas pelo analisador de shell são salvas na lista de histórico, sujeitas ao valor de HISTIGNORE . A segunda linha e as linhas subseqüentes de um comando composto de várias linhas não são testadas e são adicionadas ao histórico, independentemente do valor de HISTCONTROL .


4

Por que isso acontece?

O MacOS e o Ubuntu são configurados de maneira diferente para lidar com duplicatas no histórico de comandos do bash. Essas configurações são armazenadas em vários chamados " arquivos de ponto ". Estes assumem a forma de ~ / .bash * e também o sistema / etc / profile. Todos esses arquivos podem ser personalizados ao seu gosto e diferenciar entre shells interativos, shells de login, shells remotos etc. Esses arquivos são lidos em uma ordem específica e servem a funções específicas.

Como obter o mesmo comportamento no macOS?

Se você quiser apenas essa, personalização única de "ignorar duplicatas exatas das linhas de comando", você pode incluir algo como a resposta de Allan, ou seja, adicionar uma única linha para, por exemplo, seu arquivo bash_profile. Não existe "o caminho certo", mas inúmeras opções.

Caso essa não seja a única personalização para o seu bash, talvez essa não seja a melhor opção:

Algumas outras notas:

  • Qualquer coisa que deva estar disponível para aplicações gráficas OU para sh (ou bash invocado como sh) DEVE estar em ~ / .profile
  • ~ / .bashrc não deve produzir nada
  • Qualquer coisa que deva estar disponível apenas para shells de login deve entrar em ~ / .profile
  • Verifique se ~ / .bash_login não existe.

Isso significa que, quando as coisas se tornam mais complexas, é boa ideia para espalhar as personalizações em vários arquivos, cada um deles especializado e altamente ordenada em seu conteúdo:

Todos exportspodem residir em seu próprio arquivo para simplificar a supervisão.

Crie um arquivo que é lido pelo bash na raiz do seu diretório de usuário, por exemplo chamado .exportsque contém:

# Omit duplicates and commands that begin with a space from history.
export HISTCONTROL='ignoreboth'; 

Isso precisa ser "originado" para que o arquivo seja lido pelo bash na inicialização interativa:

Fornecendo arquivos
Se você possui muitas configurações de shell, pode dividi-las em vários subarquivos e usar a fonte incorporada para carregá-los do seu .bashrc: com adição source ~/.exportsa eles.

Como alternativa, para garantir que os arquivos realmente existam antes do carregamento

if [ -f ~/.exports ]; then
. ~/.exports
fi

O comando . ~/.exportsterá origem ~/.exportsno contexto do shell atualmente em execução.

Isso é particularmente útil para adicionar aliases, pois o arquivo separado facilita recarregá-los quando você faz alterações.


2
Como é .exportslido (fornecido)?
Fd0

1
@ fd0, por si só, não é obtido no macOS. A resposta de Allan é uma maneira adequada de conseguir isso.
user3439894

Se o valor de HISTCONTROLestiver definido .bashrce ~/.bashrcfor originado ~/.bash_profile, não haverá necessidade exportda HISTCONTROLvariável. Um shell de login interativo e um shell interativo terão a variável definida.
Fd0

@ fd0 Exatamente: se . / No caso de eu não entender: meu objetivo era fornecer uma alternativa ao arquivo A / & simultaneamente publicado por Allan, mantendo o perfil _especial, mas também o resto o mais limpo e arrumado possível, porque esse é um cenário em que muitas opções / configurações são consideradas. O seu último ponto é uma sugestão a acrescentar ou pretende ser uma correção, pois você pode perceber o método acima como "errado"? Agora, li seu comentário entre o meu e o de Allan no nível de complexidade abordado?
precisa saber é o seguinte

1

Registrar uniqely todos os novos comandos é complicado. Primeiro você precisa adicionar ~/.profileou similar:

HISTCONTROL=erasedups
PROMPT_COMMAND='history -w'

Então você precisa adicionar a ~/.bash_logout:

history -a
history -w
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.