¿Por qué la sustitución del historial de bash todavía está habilitada por defecto? [cerrado]

17

¿Alguien sabe por qué bash todavía tiene la sustitución de historial habilitada de forma predeterminada? Mi .bashrcha incluido set +Hdurante muchos años, pero algunas otras personas todavía están siendo mordidas por esta característica.

Dado que casi todo el mundo está usando terminales con funciones de copiar y pegar y bash compilado con la readlinebiblioteca y la sustitución del historial está habilitada por defecto solo en shells interactivos, ¿hay realmente alguna razón para tener la función? Ninguno de los scripts existentes se rompería incluso si esto estuviera deshabilitado por defecto para todos los shells.

Pruebe esto si no sabe por qué se rompe la sustitución del historial:

$ 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, la función tiene problemas importantes si está deshabilitada de forma predeterminada para todas las secuencias de comandos y existe una función para verificar los resultados antes de ejecutarla shopt -s histverify.)

Ver también:

Mikko Rantalainen
fuente
16
Parece que piensas que la gente no usa la sustitución de la historia. Lo uso todos los dias. Me parece a seguir más rápido ls -l foo/bar/baz/weeble.cppcon el less !$que en la memoria del comando y editarlo.
Martin Bonner apoya a Mónica el
2
@MartinBonner Para que pueda habilitarlo. La pregunta es por qué está habilitado de forma predeterminada , no por qué todavía existe.
Barmar
55
@Barmar: Claro. Pero mi punto era desafiar la suposición de que la pregunta se basa.
Martin Bonner apoya a Monica el
55
Si seguimos su razonamiento, todo lo que requiera escapar o citarse debería deshabilitarse de manera predeterminada. ¿Por qué debería necesitar escapar o citar una URL que contiene &? ¿Por qué debería necesitar escapar o citar un nombre de archivo que contiene un ?? Hay IU para personas que piensan que esto es un problema.
jcaron
3
Lo uso !$varias veces al día, y con !!bastante frecuencia también. Tengo que admitir que no uso otras sustituciones de historial tanto, pero definitivamente no estaría contento si el comportamiento predeterminado del shell que he estado usando durante años cambia repentinamente.
jcaron

Respuestas:

32

Si ya está familiarizado bash, entonces tratar con patrones de sustitución de historial no es mucho más probable que lo muerda que manejar cualquier otro personaje que sea especial para este shell. Sin embargo, si uno no está familiarizado con el shell o simplemente nunca usó sus características de sustitución del historial, obviamente será una sorpresa cuando las cadenas aparentemente sin comillas o con comillas dobles lo activen.

En un shell interactivo con sustituciones de historial habilitadas, el !carácter es especial de la misma manera que el $carácter es especial, es decir, en todas partes, a menos que se escapen con \o en cadenas de comillas simples.

En contraposición a $través, sustituciones historia no se expanden en los documentos internos, y puesto que son orientado a líneas, que, además, se suceden en las líneas donde la sustitución se inscribe en un contexto no indicada o un contexto citado doble (en esa línea cuando se escanea por separado) . Vea este informe de error para más información .

La sustitución del historial está deshabilitada en shells no interactivos (scripts) porque la capacidad del historial de comandos del shell no es necesaria allí, no porque la función tenga "problemas importantes". En un script, guardar cada comando $HISTFILEno tiene sentido, y la sustitución del historial tampoco es algo en lo que quieras confiar en un script.

Se puede debatir si se debe habilitar o no de manera predeterminada o no en shells interactivos (aunque no estoy completamente convencido de que un debate aquí sea muy importante para los bashdesarrolladores). Parece pensar que la mayoría de los bashusuarios están teniendo problemas con las expansiones del historial, pero ninguno de ustedes y yo sabemos cuán común es usarlos.

Los proyectiles Unix le permiten a uno modificar el comportamiento del proyectil para adaptarlo a sus necesidades y gustos personales. Si desea desactivar las sustituciones de historial para todos sus shells interactivos, continúe haciendo lo que está haciendo con el uso set +Hde su ~/.bashrcarchivo, o haga lobby con los bashdesarrolladores para cambiar el valor predeterminado (lo que, creo, molestaría y confundiría a más personas de lo que ayudaría) )

Kusalananda
fuente
2
@MikkoRantalainen Parece que piensa que la sustitución del historial no es algo que la mayoría de los bashusuarios están usando. No creo que ninguno de nosotros sepa lo común que es. Le sugiero que si se siente convencido de esto, envíe una solicitud de función / error a la bashlista de correo. Ver savannah.gnu.org/mail/?group=bash
Kusalananda
8
Correcto. El problema no es en realidad la sustitución de la historia, sino el hecho de que las "comillas" dobles en Bash no son realmente comillas en el sentido en que otros idiomas usan el término, sino que funcionan como un paréntesis especial. @MikkoRantalainen, ¡haz el hábito de poner cualquier cosa que no quieras que Bash interprete de manera especial entre comillas simples !
Leftaroundabout
55
@leftaroundabout Depende de lo que quieras decir con interpretación. La mayoría de los idiomas interpretan los caracteres de control en cadenas para la salida (pero se concede, no de la misma manera que en el shell cuando solo se barajan las cadenas). Las reglas de cotización de Perl también funcionan de manera similar a la shell (interpolación variable). Al igual que con cualquier lenguaje de programación, ayuda si uno puede recordar en qué idioma está trabajando actualmente.
Kusalananda
55
Mi punto es que! rara vez se usa un personaje especial " Yo diría que es al revés ... !rara vez se usa como un personaje normal que, haciéndose eco de los WTF a un lado, la cantidad de personas atrapadas es muy superior por la cantidad de personas que todavía lo usan para sustituir la historia.
TripeHound
3
-1 por desviar la culpa a una cita incorrecta. Como no! es especial para la mayoría de los shells tipo Bourne, ni en los scripts, hay muchos caminos por los cuales las personas pueden aprender razonablemente que expandirán el pero no el . Me familiaricé con el shell de Bourne , y mi primer encuentro con la sustitución de la historia fue que me mordió cuando intentaba hacer una línea rápida en un shell interactivo. Las personas que dominan el uso portátil y de secuencias de comandos de conchas tipo Bourne a menudo son mordidas al menos una vez cuando se usan . bash"$my_var some text!!"$my_var!!busybox ashbashbash
mtraceur
9

La sustitución de la historia es útil. Tomar como ejemplo

% make-me-a-sandwich
make-me-a-sandwich: Permission denied
% sudo !!
Ok.
Johan Myréen
fuente
2
¿Entonces? Si lo encuentra útil, puede habilitarlo en su .bashrc.
Barmar
3
xkcd.com/149
Walter Tross
3
@Barmar y si no lo encuentra útil, puede deshabilitarlo. Es curioso cómo funciona la simetría.
hobbs
3
@hobbs Si no sabe que existe, ¿cómo podría desactivarlo?
Barmar
2
Esta respuesta hace un buen trabajo al explicar una razón por la cual la función es útil. Creo que OP quiere entender por qué esta utilidad es suficiente para justificar este comportamiento, a pesar de que OP (y otros, como las personas que hacen varias de las preguntas relacionadas en este intercambio de pila) encuentran este comportamiento sorprendente / inesperado.
mtraceur
4

Inercia social / cultural.

Esta pregunta está en el espacio del problema de cómo los humanos trabajan, así que voy a responder desde ese ángulo, sin dar ninguna opinión sobre si la función debería estar activada o no de forma predeterminada.

Para empezar, para asegurarse de que entiende el otro lado, consideran que la molestia se siente acerca de tener que salir de su manera de desactivar la función, es la molestia que se siente si tenían que salir de su manera de activar la característica.

Combine lo anterior con el hecho de que suficientes bashusuarios usan la función, las sugerencias de eliminarla o desactivarla de forma predeterminada se encuentran con la resistencia de las personas que ya se sienten cómodas con que esté allí de manera predeterminada.

Además, bashes el shell predeterminado para muchas personas (no solo en el inicio de sesión predeterminado o en el sentido del shell del sistema, sino en un sentido psicológico). Si su marco de referencia para las citas de shell es bash, si ese es el shell que aprendió primero, el hecho de que !sea ​​un personaje especial de shell se sentirá natural y automático para usted (o al menos, cuando lo aprenda por primera vez, será solo parte de la forma en que es el shell, solo una peculiaridad para aceptar entre muchos).

Y si lo piensa, muchos bashusuarios probablemente encuentren la sintaxis de sustitución del historial en un contexto positivo : lo leen o alguien se lo muestra y ven la posible utilidad, cuando recién están aprendiendo bash.

Proviene del mundo periférico de otros proyectiles tipo Bourne, que sería mordido por !ser especial y, por lo tanto, estaría inclinado a verlo negativamente: porque si está acostumbrado a los proyectiles donde nunca tuvo la función, entonces su primer la exposición será cuando te atornille cuando intentes hacer algo rápidamente.

TL; DR: a la mayoría de los usuarios probablemente no les importa mucho cuál es el valor predeterminado de cualquier manera, a algunos usuarios les gusta la función y tienen la gran ventaja de que ya es así, y no ha habido suficientes personas que aboguen activamente contra la función para superar eso.

mtraceur
fuente
2
No, no es solo cuando viene de otros proyectiles. He conocido a esta función desde hace años en bashy todavía es mordido por sorpresa, ya que solo citar no siempre funciona en la !causa de la fractura bashaplicación.
Philippos
@Philippos Eso es aterrador (bueno, no exactamente aterrador ... pero algún tipo de cualitativo negativo angustiante). Gracias por señalar esto. Intentaré volver a visitar esta respuesta más tarde para trabajar su punto en mi respuesta una vez que haya pensado en una buena manera de integrarla.
mtraceur
2

¿Por qué la sustitución del historial de bash todavía está habilitada por defecto?

Debido a que muchas personas lo usan, y las personas que usan un bash shell interactivo probablemente deberían conocer las reglas para evitar problemas y generalmente encontrarán que ayuda más de lo que duele.

Mi .bashrc ha incluido set + H durante muchos años, pero algunas otras personas todavía están siendo mordidas por esta característica.

Por lo tanto, es una característica que no usa, eso no significa que la mayoría de los usuarios no la usen. Puede solicitar que se cambie el valor predeterminado, pero debe mirar A) la porción de personas que se preocupan , y B) la proporción de personas que lo prefieren a su manera. Las personas a las que les importa y no les gusta probablemente ya lo tienen discapacitado. Cambiarlo ayudaría cuando obtengan una cuenta en una computadora nueva. Personas que se preocupan y les gusta debería actualizar su configuración en cada computadora que usan y en cada cuenta que obtengan en el futuro.

Dado que casi todo el mundo está usando terminales con funciones de copiar y pegar

Una opción más complicada en mi opinión ...

¿Hay realmente alguna razón para tener la función? Ninguno de los scripts existentes se rompería incluso si esto estuviera deshabilitado por defecto para todos los shells.

Sí, la gente lo encuentra útil. ¿De qué sirve tener un control remoto dado que solía poder levantarse y cambiar el canal?

(Claramente, la función tiene problemas importantes si está deshabilitada de manera predeterminada para todos los scripts y existe una función para verificar los resultados antes de ejecutar: shopt -s histverify).

La historia realmente no tiene sentido en los scripts, pero lo más importante es que podría causar problemas de seguridad. En su caso, podría evitar el problema utilizando comillas simples. No recuerdo que esto haya causado un problema para mí, así que no sé cómo puedes decir que tiene "problemas importantes". ¿Te ha causado un problema real o te molestó tener que configurar tus valores predeterminados en una computadora nueva?

No veo cómo es diferente de tener que escapar o usar comillas simples en esto si realmente quieres obtener algo de dinero:

$ echo "Give me $50 or the cat gets it"
Give me $0 or the cat gets it
Jason Goemaat
fuente
2
Ver las preguntas relacionadas (columna derecha); La mayoría de las preguntas afectan a esta característica por accidente y suponen que el caparazón está roto. Personalmente, aprendí sobre esta característica hace mucho tiempo debido al hecho de que accidentalmente utilicé la secuencia de caracteres que causó una salida incorrecta. Me habría salvado shopt -s histverifypero eso no estaba activado por defecto. Además, averiguar la causa por sí mismo es bastante difícil debido a que el mensaje de error es críptico ( "evento no encontrado") y la secuencia de caracteres que lo activa es difícil de Google para.
Mikko Rantalainen
1
La gente se genuinamente mordidos por esta característica debido a que la sintaxis del shell "universal" cuenta como $estar dentro de especial "..."son una de las primeras cosas que las personas aprenden sobre la cáscara, mientras que el hecho de que !está en el interior especial "..."(pero sólo en modo interactivo) es menos conocida en términos generales, por lo general no se enseña de manera inmediata / prominente, y es bashespecífico. Además, Bourne como conchas en su mayoría tienen una simetría entre el texto-in-a-escritura y el texto-a-la-interactiva-shell, por lo que puede copaste generalmente de una a la otra y hacer que trabaje el mismo - y crea esta función Una de las únicas excepciones.
mtraceur
1
No veo cómo es diferente de tener que escapar o usar comillas simples Verdadero para zsh, cuando las comillas simples !siempre funcionan, pero no para bash, donde la implementación produce resultados inesperados . Dices, deberíamos conocer las reglas , bueno, ¿conocías esa regla vinculada?
Philippos