¿Por qué Mac Terminal recuerda dos comandos consecutivos cuando son iguales?

10

Empecé a usar Mac recientemente y antes solía trabajar en Ubuntu.

Supongamos que ejecuto estos comandos uno por uno en mi terminal:

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

Ahora suponga que quiero volver a ejecutar python main.py, así que haré clic en la tecla arriba. Necesitaré hacer clic en la tecla hacia arriba solo dos veces en Ubuntu, pero 7 veces en Mac.

Si dos comandos consecutivos son iguales, entonces el terminal debe recordar solo un comando en lugar de recordar dos comandos diferentes.

¿Cómo puedo hacer que esto suceda en macOS?

as2d3
fuente
66
Simplemente pedante, en realidad no es el terminal mac lo que está haciendo esto. Es bash, tu shell se ejecuta en la terminal. Hay muchos shells y es posible y común reemplazar el shell predeterminado con algo más zshy personalizar aún más zsh con varios scripts.
Gman

Respuestas:

13

Debe agregar la variable de entorno HISTCONTROL a su .bash_profile. En su .bash_profileagregar la siguiente línea:

export HISTCONTROL=ignoreboth:erasedups

Cierre y reinicie su sesión de bash y los engaños deberían desaparecer. Alternativamente, podría ejecutar esa misma línea y surtirá efecto para esa sesión (úsela para probarla).


Desde la páginabash del manual para (en la Terminal):

HISTCONTROL
Una lista de valores separados por dos puntos que controlan cómo se guardan los comandos en la lista del historial. Si la lista de valores incluye ignorespace , las líneas que comienzan con un carácter de espacio no se guardan en la lista del historial. Un valor de ignoredups hace que las líneas que coinciden con la entrada del historial anterior no se guarden. Un valor de ignoreboth es la abreviatura de ignorespace e ignoredups . Un valor de borrados hace que todas las líneas anteriores que coinciden con la línea actual se eliminen de la lista del historial antes de que se guarde esa línea. Cualquier valor que no esté en la lista anterior se ignora. Si HISTCONTROLno está configurado o no incluye un valor válido, todas las líneas leídas por el analizador de shell se guardan en la lista del historial, sujetas al valor de HISTIGNORE . La segunda línea y las siguientes de un comando compuesto de varias líneas no se prueban y se agregan al historial independientemente del valor de HISTCONTROL .

Alano
fuente
4

¿Por qué pasó esto?

MacOS y Ubuntu están configurados de manera diferente para manejar duplicados en el historial de comandos de bash. Estas configuraciones se almacenan en una serie de los llamados " archivos de puntos ". Estos toman la forma de ~ / .bash * así como también el sistema / etc / profile. Todos estos archivos pueden personalizarse a su gusto y diferenciar entre shells interactivos, shells de inicio de sesión, shells remotos, etc. Estos archivos se leen en un orden específico y cumplen funciones específicas.

¿Cómo obtener el mismo comportamiento en macOS?

Si solo desea esta única personalización de "ignorar los duplicados exactos de las líneas de comando", puede ir con algo como la respuesta de Allan, es decir, agregar una sola línea simple, por ejemplo, a su archivo bash_profile. No existe "la forma correcta", sino innumerables opciones.

En caso de que esta no sea la única personalización para su bash, esta podría no ser la mejor opción:

Algunas otras notas:

  • Cualquier cosa que debería estar disponible para aplicaciones gráficas O para sh (o bash invocado como sh) DEBE estar en ~ / .profile
  • ~ / .bashrc no debe mostrar nada
  • Cualquier cosa que solo esté disponible para iniciar sesión en shells debe ir en ~ / .profile
  • Asegúrese de que ~ / .bash_login no existe.

Eso significa que, cuando las cosas se vuelven más complejos, es buena idea para extender las personalizaciones en varios archivos, cada uno de ellos especializado y altamente ordenada en sus contenidos:

Todos exportspueden residir en su propio archivo para una supervisión simplificada.

Cree un archivo que bash lea en la raíz de su directorio de usuario, por ejemplo, llamado .exportsque contiene:

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

Esto debe "originarse" para que bash lea el archivo en el inicio interactivo:

Aprovisionamiento de archivos
Si tiene muchas configuraciones de shell, es posible que desee dividirlas en varios subarchivos y usar la fuente incorporada para cargarlos desde su .bashrc: con agregarlos source ~/.exports.

Alternativamente, para garantizar que los archivos realmente existan antes de cargar

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

El comando . ~/.exportsse originará ~/.exportsen el contexto del shell actualmente en ejecución.

Esto es particularmente útil para agregar alias, el archivo separado hace que sea más fácil volver a cargarlos cuando realiza cambios.

LаngLаngС
fuente
2
¿Cómo .exportsse lee (fuente)?
fd0
1
@ fd0, por sí mismo, no se obtiene en macOS. La respuesta de Allan es una forma adecuada de lograr esto.
user3439894
Si el valor de HISTCONTROLse establece .bashrcy ~/.bashrcse obtiene, ~/.bash_profileentonces no hay necesidad de exportla HISTCONTROLvariable. Tanto un shell de inicio de sesión interactivo como un shell interactivo tendrán la variable establecida.
fd0
@ fd0 Exactamente: si . / En caso de que no entiendo: mi punto era proporcionar una alternativa a la publicación simultánea de Allan de A / & manteniendo el perfil _p_ pero también el resto lo más limpio y ordenado posible porque esto es para un escenario donde se consideran muchas opciones / configuraciones. ¿Su último punto es una sugerencia para agregar o significa una corrección, ya que puede percibir el método anterior como 'incorrecto'? Ahora, leí tu comentario entre el mío y el de Allan en el nivel de complejidad abordado.
LаngLаngС
1

Grabar unívocamente cada nuevo comando es complicado. Primero necesita agregar ~/.profileo similar:

HISTCONTROL=erasedups
PROMPT_COMMAND='history -w'

Entonces necesitas agregar a ~/.bash_logout:

history -a
history -w
Steven Penny
fuente