Fish-shell: && no funciona

Creado en 19 jun. 2012  ·  98Comentarios  ·  Fuente: fish-shell/fish-shell

cd .. && pwd devuelve el siguiente error:

fish: Expected a command name, got token of type 'Run job in background'. Did you mean 'COMMAND; and COMMAND'? See the help section for the 'and' builtin command by typing 'help and'.
cd .. && pwd

Obviamente, puedo usar la sintaxis COMMAND; and COMMAND , pero sería bueno si Fish lo admitiera.

¡Gracias!

enhancement

Comentario más útil

|| también sería bueno.

Todos 98 comentarios

|| también sería bueno.

Solo quiero expresar una opinión alternativa.
'||' y '&&' son los elementos de sintaxis, mientras que 'y' y 'or' son comandos simples. Este enfoque es simple y limpio.
Creo que no es una buena idea introducir elementos de sintaxis adicionales para implementar la capacidad ya existente.
Es diferente de bash, pero está bien.

También votaría por tener && y || ya que este es un azúcar sintáctico de uso común y sería muy bueno tenerlo con facilidad de uso.

+1 a la sugerencia de maxfl.

+1 a la sugerencia de maxfl.

Ruby también tiene palabras clave and y or .

+1

No tengo ninguna objeción si alguien quiere hacerse cargo de esto.

-1 para implementar && / || y +1 a maxfl. Y realmente no veo la razón por la que debería implementarse. No es azúcar sintáctico, en bash es solo la sintaxis y en fish esta sintaxis no existe. También sería realmente inútil como azúcar sintáctico como '; o' toma exactamente tantas pulsaciones de teclas como '||'.

Me gusta la simplicidad de los comandos and y or , pero un problema es que hacen que las declaraciones if sean raras. Por ejemplo:

if begin ; [ a = b ] ; and [ c = d ] ; end
   ...

en comparación con

if [ a = b ] && [ c = d ]
    ...

¿Alguien tiene ideas para mejorar eso?

if test a = b -a c = d # or [ ] syntax, but I didn't particularly liked it
    ...

Pero si bien eso funciona para test incorporado, no funciona en ningún otro lugar. Supongamos que los elementos integrados a y b deben volver a ser verdaderos para ejecutar c y d . Entonces, podríamos escribirlo así.

and b
and begin
    c
    d
end

O con sintaxis de bloque y if .

if begin
        a
        and b
    end
    c
    d
end

O hacer conditonal anidado.

if a
    if b
        c
        d
    end
end

Por otra parte, no estoy seguro de la frecuencia con la que se necesita este truco, pero searchco.de dice que && se usa principalmente con test incorporado (o para efectos secundarios).

No estoy realmente seguro de si fish necesitaría otra sintaxis útil solo en casos excepcionales. Ya se siente como [ , excepto que uno tenía que quedarse porque de todos modos es binario (como test ). No se siente particularmente sospechoso, pero está aquí, porque es binario (a diferencia de [[ que me alegro de que Fish no sea compatible).

Tener dos sintaxis (o en este caso, incluso tres) sería bastante confuso. ¿Qué sintaxis debo utilizar?

if a
    b
end
a; and b
a && b

Parece que && es el más corto, excepto que es la mitad de la verdad. Escribir ;and requiere exactamente el mismo número de pulsaciones de tecla (porque & implica Shift). Agregar && alentaría a agregar sintaxis adicional (nuevamente, and se analiza de una manera especial, porque puede insertar palabras clave como begin después, y funcionan).

El problema es que tenemos las sintaxis ; and y ; or ; las nuevas sintaxis se sentirían como duplicadas. Ya son algo mágicos (no son solo una función de script de shell que verifica la variable $status ), por lo que no tendría problemas si fueran reemplazados por && y || .

No estoy seguro de qué pensar. Creo que debería haber una sola sintaxis para hacerlo. Me gustan ; and y ; or , pero no tendría problemas con && y || , siempre que se eliminen las sintaxis antiguas. Pero considerando la compatibilidad con versiones anteriores, preferiría quedarme con ; and y ; or . Quizás si begin fuera más corto (como llaves en bash) ... pero eso no se sentiría sospechoso.

¿Por qué no admitir un [[incorporado como hace bash? Sería más rápido (ver: eco incorporado) y sería compatible con && y || operadores dentro de [[y]] para emular el comportamiento y / o.

Debido a que [[ no es un comando real, solo existe en bash. El problema es que [[ es como [ (en su mayoría), excepto que tiene reglas especiales de análisis para evitar comillas innecesarias. Consulte la ley de ortogonalidad y la ley de descubrimiento para ver por qué no está en peces.

De hecho, estoy casi seguro de que [ no existiría debido a la ley de descubrimiento y la ley de ortogonalidad, pero lo hace porque es binario en /usr/bin . test es más sospechoso, porque puede descubrirlo al completar la pestaña. Pero bloquear binarios sería bastante arbitrario, por lo que también podría implementarlo como incorporado.

Por ejemplo, en bash [[ cita automáticamente todas las cadenas.

[[ abc = $variable ]]

Pero eso no es necesario en los peces porque el comportamiento de división de espacios en blanco no existe. Además, cita automáticamente && , || , < y > porque es una característica sintáctica. En pescado, && es -a , || es -o . < y > ni siquiera existen.

También tiene operador =~ . En fish , puede usar quiet grep para eso.

echo $ANSWER | grep -qE '^y(es)?$'

Además, bash tiene < y > . Verifican cualquier cadena que sea mayor o menor que otra cadena. Esto rara vez es útil.

Y, al usar los operadores = y != , puede usar la sintaxis globular, al igual que usaría expresiones regulares. Nuevamente, use grep silencioso para eso.

[[ abc = a* ]]

Además, el [[ se define para tener -e , -nt , -ot , -ef y ! , pero fish ya los tiene en test incorporados.

Agregar [[ solo agregaría otra palabra clave, que no sería realmente detectable y realmente no agregaría mucha funcionalidad. La única funcionalidad interesante es =~ , pero el grep silencioso (o Perl) puede hacer lo mismo, sin agregar una nueva sintaxis. Además, no deberíamos agregar todo al shell. No creo que necesitemos tener expresiones regulares incorporadas.

Bueno, no quise decir necesariamente que deberíamos reimplementar la función [[ bash, sino que debería introducirse como una construcción sintáctica con sus propias propiedades. Es decir, fish comparte muchas palabras clave y construcciones que se parecen a las de bash, pero son diferentes, así que no veo cómo esto no sería así.

Aunque, según lo que dijiste, quizás implementar nuestro propio test sería una mejor construcción, aunque, renombrado a algo como cond , como la forma en que Fish implementa un math incorporado en su lugar de expr . Incluso podríamos ir al punto de implementar cosas como <y>, sin embargo, usando ordenación natural (numérica) en lugar de ordenación lexicográfica, para que funcione tanto en números como en cadenas.

@Undeterminant builtin [[vs builtin [vs / bin / [las diferencias sutiles ya son confusas en bash; por favor no empeoremos las cosas añadiendo bash - [[vs fish - [[diferencias sutiles!
Además, el espíritu de bash [[viola la ley de la ortogonalidad - "arregla" y / o pero solo para condiciones específicas que soporta el constructo.

Es irónico que if commands...; then ...; fi bash admitiría fácilmente peces y / o entre if...then . Pero no queremos un "entonces". Quizás lo que hay que arreglar es hacer que comenzar ... terminar sea más fácil.

Aquí hay una idea extraña (no estoy seguro de que me guste):

if (foo; and bar)
  ...
end

Actualmente (...) al inicio del comando es ilegal; la lectura natural es ejecutar esto y usar la salida como nombre de comando, pero requerimos eval para eso.
Si estamos seguros de que nunca permitiremos esa lectura directamente, podríamos reutilizar (...) para que signifique begin ...; end .
No capturar la salida estándar en esta posición es inconsistente, pero de apariencia muy compacta y limpia.

Lo que odio de esto es que if (...) ruega por otro significado: capture la salida y asígnele alguna interpretación booleana. Por ejemplo, if (math 2 \< 4) - math no devuelve un estado, imprime 0 o 1 en la salida estándar. Un uso importante sería if $saved_bool .
No creo que esto sea práctico: no existe una única asignación correcta de significados booleanos a las cadenas, especialmente porque 0/1 se confunden irremediablemente. Pero cuando se encuentra por primera vez con if (...) , parece una suposición razonable.

Por razones de compatibilidad, proporcione los operadores comunes que se encuentran en bash y zsh. Cuanto más fácil sea para los nuevos usuarios copiar y pegar la mayor parte de la funcionalidad de su caparazón anterior, mejor será la tasa de absorción de peces. Me he dado cuenta de que, si bien me gusta más el pescado en muchos aspectos, algunos de estos pequeños obstáculos tontos hacen que sea más una molestia que un beneficio cuando vengo con más de 15 años de personalizaciones de caparazón que realmente no deberían ser un problema para respaldar. .

Honestamente, no veo && como un "pequeño obstáculo tonto". No sería difícil de aprender si tratara a fish como su propio idioma en lugar de un "caparazón de reemplazo" como lo es zsh. Si lees el tutorial sobre cómo funciona el pescado de principio a fin, no creo que sea difícil de entender.

Tener algo como command1; and command2 deja más claro que and es una ejecución condicional de command2 y no solo una unión entre command1 y command2 .

Pero @Undeterminant , no lo está viendo como la mayoría de la gente lo ve al principio cuando lo descubre inicialmente, etc. Deje que ese sentimiento o nivel de competencia llegue con el tiempo. Por ejemplo, traje cientos de líneas de una antigua configuración heredada y, sinceramente, no tengo tiempo para convertir inmediatamente todo lo que necesita ser convertido. Estoy encontrando rarezas en las que no hay un número de línea que regrese de pescado con respecto a dónde está mi problema dentro de mis configuraciones anteriores.

Puedo entender su perspectiva, pero está sesgada con respecto a alguien que quiere hacer el cambio y le gustaría hacerlo con el tiempo en lugar de pasar por encima de una gran joroba. Por favor, no me malinterprete, si no me importara el pescado y, por lo tanto, trato de dar información, ciertamente volvería a zsh ahora mismo. Siento que este tipo de pensamiento y razonamiento es importante para abrir la puerta un poco más a los recién llegados.

Así que sí, tiene razón en lo que respecta a la legibilidad, pero dejemos que lo anterior funcione y démosle una advertencia en lugar de un error para que la gente deje de hacerlo.

@ylluminate Te estás engañando. Incluso si fish admitía && , aún no podría usar su configuración de bash o zsh, porque hay más diferencias en la sintaxis de scripting que solo los operadores lógicos.

Exactamente. fish es funcionalmente diferente, lo que significa que no debe simplemente copiar y pegar el código directamente. Si su código está escrito en bash, a menos que exista una necesidad explícita de convertirlo en fish, simplemente manténgalo como bash; son idiomas separados.

Entonces
si lo hago
comando1 && comando2
en pescado sugiere que en su lugar escribo
comando1; y command2

¿Alguien realmente cree que (en la línea de comandos) la segunda opción es más limpia, más futurista y más fácil de escribir?

Es más limpio, porque se basa en la sintaxis existente para ejecutar comandos, en lugar de introducir una nueva sintaxis.

Considere en bash:

foo & bar # executes foo in the background, then bar in the foreground
foo && bar # executes foo in the foreground, then executes bar if foo has a zero exit status
foo & bar && baz & qux # left as an exercise for the reader

Este es el tipo de tonterías que esperamos evitar usando comandos en lugar de una sintaxis especial.

Esta decisión de diseño definitivamente incurre en un costo, especialmente en las declaraciones if, que deberíamos intentar reducir. Pero deberíamos abordarlo desde una posición de "encontremos formas de mejorar el pescado dentro de su filosofía de diseño" en lugar de "busquemos formas de hacer que el pescado se parezca más a otras conchas".

Su código hace lo siguiente, ¿verdad (asumiendo que puede usar & con bloques)?

foo &
if bar
    baz
end &
qux

Para mí, parece artificial. Además, si la sintaxis de & es tan confusa, ¿por qué no crear background incorporado, o algo así?

Creo que de hecho es un argumento para hacer de los antecedentes algo incorporado, aunque no estoy proponiendo que lo hagamos realmente.

El problema con ; and y ; or es que interactúan mal con las tuberías. condition; and echo stuff | grep stuff no funciona, mientras que condition && echo stuff | grep stuff sí. No veo ninguna forma de evitar este problema, excepto para agregar una sintaxis especial.

and echo stuff | grep stuff parece funcionar para mí. ¿Puedes explicar cómo está roto?

@ridiculousfish Este es el caso que descubrí al probar pescado. La expresión o es verdadera fuera de la declaración if pero (¿parece ser?) Falsa cuando se usa en una declaración if. ¿A menos que me esté perdiendo algo aquí?

root@smogon-dev ~# test 0 = 1; or echo stuff | grep stuff
stuff
root@smogon-dev ~# echo $status
0
root@smogon-dev ~# if test 0 = 1; or echo stuff | grep stuff
                       echo Success
                   else
                       echo Failure
                   end
Failure

Comparar con bash:

~/smogon/bin$ [[ 0 == 1 ]] || echo stuff | grep stuff
stuff
~/smogon/bin$ echo $?
0
~/smogon/bin$ if [[ 0 == 1 ]] || echo stuff | grep stuff; then
> echo Success
> else
> echo Failure
> fi
stuff
Success

En este caso:

if test 0 = 1; or echo stuff | grep stuff

podría ser más claro si estuviera escrito así:

if test 0 = 1
    or echo stuff | grep stuff
    ...

¡La instrucción or está en el cuerpo if! Dado que los valores booleanos son comandos, no tienen precedencia especial.

Puede usar begin / end como "paréntesis":

if begin; test 0 = 1; or echo stuff | grep stuff ; end
    ...

Entonces creo que no está relacionado con las tuberías, sino con la precedencia.

Como puede ver en este error, hay muchas opiniones sobre si fish debería admitir operadores booleanos :)

Entonces, gracias a todos por la energía que pusieron aquí.

Mi intención no es provocar la discusión sobre qué cosas son mejores o no. Es solo una cosa práctica.
Como la mayoría de ustedes, tengo mis propios scripts para ejecutar. Incluso en cosas muy simples, la condición && garantiza el éxito del comando (salida 0), mientras que ";" simplemente siga adelante sin importarle lo que haya sucedido. ¿Correcto? Entonces, no son iguales en absoluto. Espero que todos estemos de acuerdo en esto. :)

Entonces, tengo mis guiones y ninguno de ellos funciona con peces. Sí, uso mucho &&. Pero esto también sucede con cualquier código en la red con bash, generalmente usando && también. Para abreviar, ¡lo que pasa es que ya no puedo usar mis códigos! :D

Me preguntaba ... ¿Es posible establecer una función o definición en el archivo de configuración de peces para corregir este comportamiento SOLAMENTE (es decir, solo &&) y devolverlo como está en el bash tradicional? ¿Es posible? ¿Plausible? ¿Realizable?

Nuevamente, estoy de acuerdo en que el uso de "y" puede ser más agradable y claro. Pero no funciona con mi código o, en general, con cualquier código bash para principiantes anterior. Entonces, en lugar de cambiar el código ya escrito reemplazando && (... no sucederá ... y probablemente no funcionará) sería más fácil permitir que los peces entiendan el bash tradicional si alguien quiere o necesita, ¿no?

¡¡Todos los mejores chicos, y gracias de nuevo por el esfuerzo !!

¿Alguna vez nos hemos acercado a la compatibilidad total con los scripts bash / zsh ? Renuncié a fish según mis comentarios anteriores porque no me voy a tomar el tiempo para convertir toda la infraestructura que ya he construido en mis entornos de shell en tantas estaciones de trabajo y servidores. Me encantaría intentarlo de nuevo si estamos más cerca. De lo contrario, seguiré vendiendo sin él. Gracias.

@rhoconlinux Cambiar Fish para que admita && no hará que sus scripts bash funcionen. Hay muchas más diferencias que eso.

No entendí tu respuesta ^ _ ^
¿Es posible definir un alias o una función para el problema &&?

@rhoconlinux No, tendrías que modificar el analizador Fish (en C ++). Mi punto es que si Fish admitiera && , sus scripts Bash aún no se ejecutarían, debido a todas las demás diferencias entre Fish y Bash.

@kballard ¡ay! hmmm ... Estoy tan triste de escuchar esto. Lo entiendo ahora. Super claro. :)

Gracias por los comentarios superrápidos. Usaré fish para una mejor experiencia diaria y entonces tendré una terminal bash para mis cosas.

¡Salud! : +1:

Si && es una preocupación, es fácil lidiar con ella.

sed 's/&&/; and /' ~/.bashrc > ~/.config/fish/config.fish

Pero es poco probable que esto sea lo único que deba hacer. Lo que quiere decir es una implementación de # 522.

Yo diría que la principal motivación para la compatibilidad con && no es convertir
bases de código pero copiar y pegar de Internet.
Por ejemplo, veo un fragmento de sudo add-apt-repo... && sudo apt-get update && sudo apt-get install ... , solo quiero copiar y pegar pero falla.

Esto no es algo que podamos resolver mediante la educación; siempre habrá
fragmentos para pegar y utilizarán la sintaxis estándar [ba] sh.
Y && es, con mucho, el problema número uno con el que me estoy topando.
( export FOO=bar es # 2 pero se puede resolver con function export; set -x -g (echo $argv | sed 's/=/\n/'); end .)

Sin embargo, no es un problema profundo: me he acostumbrado a escribir
bash , pegar, Ctrl + D.
Mmm, estoy tentado de agregar un atajo de teclado para ejecutar el actual / anterior
línea de comandos en bash.

Mis dos centavos sobre el tema:
Estoy trabajando en una herramienta de implementación (https://github.com/andres-montanez/Magallanes) que realiza llamadas de comandos de shell, y la mayoría de los usuarios y colaboradores utilizarán un shell bash. Entonces, por supuesto, aquí y allá '&&' se usan para encadenar comandos.

Hay soluciones obvias (como pasar todos los comandos explícitamente a bash)
Pero eso trae una serie de puntos débiles. Por un lado, puede haber efectos secundarios extraños (es decir, la RUTA y otras variables no se definen de la misma manera), significa piratear algunas partes centrales de la herramienta para ese único propósito, y necesito fusionar mis correcciones de una versión a otra. cada vez que actualizo.

&& es solo una de las muchas funciones de bash con las que fish no es compatible, pero podría ser la más básica y la más utilizada. Por ejemplo, la herramienta anterior está en PHP, por lo que cualquier medio complejo se hace en PHP y solo se pasan al shell los comandos básicos del sistema. Es frustrante encontrar incompatibilidades de sintaxis con un caso de uso tan mínimo.

Estoy completamente de acuerdo con lo que dijo @cben && es, en mi opinión, un caso especial porque hay cientos de fragmentos de código en línea donde la única diferencia entre copiar y pegar o no es el soporte para && .
Si bien estoy de acuerdo en que es importante tener en cuenta cómo avanza el pez en términos de sintaxis, etc. Creo que esto es algo que facilitaría mucho la vida de muchos desarrolladores que usan o quieren usar peces. Sé que parece un simple reemplazo && con ; and pero siempre es molesto y me hace sentir un poco incómodo cuando le digo a otras personas lo increíble que es el pescado, pero luego tengo que jugar. y cambiar algunas palabras clave, por lo general se preguntan por qué tengo que cambiar algo tan simple. Entonces tengo que defender a los peces y eso no es un gran caso para promoverlos.
A veces, son las cosas más simples las que pueden tener el mayor impacto.
En resumen, estoy a favor de permitir la sintaxis bash && .

Estoy de acuerdo con lo que dijeron @Globegitter y @cben . Una gran cantidad de scripts y programas depende de && y || . Utilizo fish shell en mi estación de trabajo y sería bueno tener compatibilidad cross-shell al escribir scripts.

Dado que hay muchas diferencias significativas entre el scripting Fish y el scripting Bash más allá de solo && y || , ¿por qué todos los que comentan aquí creen que hacer que Fish acepte && sería ser significativo de alguna manera? Si necesita ejecutar un fragmento de código Bash, simplemente ejecute bash , ejecute el fragmento y luego vuelva a Fish.

Creo que a mucha gente le gustaría "convertirse" en pescado, pero tienen la infraestructura necesaria. Yo, por ejemplo, tengo 15 años de scripts de shell solo en mi estación de trabajo (sin mencionar otros servidores en los que también me gustaría ejecutar fish) en los que no quiero tener que dedicar tiempo a convertir. No me importa hurgar y hacer que las cosas funcionen "al estilo del pez" en el transcurso de varios meses, pero no hay forma de que pueda hacer ese tipo de inversión inicial en mi flujo de trabajo para cambiar a otro caparazón.

Creo que el pescado tendría una afluencia significativa de usuarios si se abordara el problema de compatibilidad general, pero no parece que esto sea algo prioritario para el proyecto por lo que dicen otros que trabajan en el desarrollo de peces. Mantengo mis ojos en esto por esta misma razón, ya que eventualmente me gustaría pasar a pescar si el paisaje cambia en este sentido.

Con respecto a simplemente ejecutar bash o zsh según sea necesario, eso sería una cantidad significativa de ejecutar esos shells en mi caso y es una tontería seguir este camino de lo contrario.

@kballard Tengo un flujo de trabajo ideal para el 95% de las secuencias de comandos que hago con fish: cmd + C una secuencia de comandos muy simple de otra fuente, cmd + tab a iTerm, cmd + v y Enter. Eso es todo lo que quiero hacer, nada de bash extra o lo que sea, nada más. La mayoría de las veces, lo único que impide que estos scripts funcionen con este flujo de trabajo exacto es que hay un && presente. Así que esa es la razón por la que para mí y supongo que la mayoría de los que están aquí para resolver este problema sería muy útil.
Si no lo experimenta usted mismo, créame, se suma y realmente se queda en su mente si su flujo de trabajo se interrumpe con tanta frecuencia.

Me encanta el pescado para todo lo demás y es por eso que no pude volver atrás, pero esta cosa simple es lo que evita que sea increíble para mí y supongo que algunos de los otros aquí.

Aqui tienes. Una vez que aterrice el PR # 1633, puede tomar lo siguiente y guardarlo en ~/.config/fish/functions/fish_user_key_bindings.fish :

function handle_input_bash_conditional --description 'Function used for binding to replace && and ||'
    # This function is expected to be called with a single argument of either & or |
    # The argument indicates which key was pressed to invoke this function
    if begin; commandline --search-mode; or commandline --paging-mode; end
        # search or paging mode; use normal behavior
        commandline -i $argv[1]
        return
    end
    # is our cursor positioned after a '&'/'|'?
    switch (commandline -c)[-1]
    case \*$argv[1]
        # experimentally, `commandline -t` only prints string-type tokens,
        # so it prints nothing for the background operator. We need -c as well
        # so if the cursor is after & in `&wat` it doesn't print "wat".
        if test -z (commandline -c -t)[-1]
            # Ideally we'd just emit a backspace and then insert the text
            # but injected readline functions run after any commandline modifications.
            # So instead we have to build the new commandline
            #
            # NB: We could really use some string manipulation operators and some basic math support.
            # The `math` function is actually a wrawpper around `bc` which is kind of terrible.
            # Instead we're going to use `expr`, which is a bit lighter-weight.

            # get the cursor position
            set -l count (commandline -C)
            # calculate count-1 and count+1 to give to `cut`
            set -l prefix (expr $count - 1)
            set -l suffix (expr $count + 1)
            # cut doesn't like 1-0 so we need to special-case that
            set -l cutlist 1-$prefix,$suffix-
            if test "$prefix" = 0
                set cutlist $suffix-
            end
            commandline (commandline | cut -c $cutlist)
            commandline -C $prefix
            if test $argv[1] = '&'
                commandline -i '; and '
            else
                commandline -i '; or '
            end
            return
        end
    end
    # no special behavior, insert the character
    commandline -i $argv[1]
end

function fish_user_key_bindings
    bind \& 'handle_input_bash_conditional \&'
    bind \| 'handle_input_bash_conditional \|'
end

Esto une & y | y hace que al escribir && o || se traduzca automáticamente en el ; and / ; or apropiado command one && command two y hacer que funcione.

Tenga en cuenta que hasta que se acepte el PR # 1633, este script funcionará para _typing_ && / || pero no funcionará para pegarlo.

@kballard ¡ Vaya, es una gran noticia! Muchas gracias.

Parece que esto en realidad no maneja el modo de búsqueda correctamente (no estoy seguro sobre el modo de buscapersonas; no tengo claro qué comprende exactamente eso). Pulsando & o | durante la búsqueda finaliza la búsqueda. Dicho eso, no sé cómo manejar eso.

Actualicé el script con una corrección de errores para escribir | o & en un comando de varias líneas.

@kballard Vi que el PR ha aterrizado. Entonces, ¿el script que pegó anteriormente debería hacer que && funcione con el último maestro?

Sí, debería. Pruébelo y avíseme si tiene algún problema.

-Kevin

El 1 de septiembre de 2014, a la 1:14 a. M., Markus Padourek [email protected] escribió:

@kballard Vi que el PR ha aterrizado. Entonces, ¿el script que pegaste arriba debería hacer que && funcione con el último maestro?

-
Responda a este correo electrónico directamente o véalo en GitHub.

Probé este script con la nueva versión 2.1.1 lanzada hace unos días y no parece funcionar. ¿Tendré que esperar hasta la 2.2? ¡Gracias!

@pragmattica : 2.1.1 fue la versión de

@xfix : OK. Gracias por hacérmelo saber. ¡No puedo esperar hasta la 2.2!

IMPRESIONANTE: +1:

¿Hay algún registro de cambios en ejecución disponible? Parece que la raíz CHANGELOG está bastante desactualizada.

@pragmattica Ahora que echo 'test1' && echo 'test2'; convierte en echo test1 &; and echo 'test2';

¿Podría haber un problema en algún lugar dentro de fish_user_key_bindings.fish ? (Intentaré revisarlo yo mismo, pero mi conocimiento del script fish / bash es un poco inestable)

Editar: Sin embargo, parece funcionar cuando escribe un comando con && . Sería un poco agradable si sucediera en el espacio posterior, pero eso no es realmente importante. Genial que la mitad esté funcionando :)

-1 a símbolos extraños :

if [[ a = b ]]; and [[ b = a ]]; or [[ c = b ]]; then echo hello; and echo world; done

+1 a símbolos simples :

if [[ a = b ]] && [[ b = a ]] || [[ c = b ]]; then echo hello && echo world; done

Aaahhh Creo que sé cuál es el problema @pragmattica, el comando commandline devuelve el búfer sin comillas. Sí, eso parece ser. Entonces, una vez que se corrige https://github.com/fish-shell/fish-shell/issues/2210, el script anterior también debe arreglarse.

¿Esto todavía se empieza a considerar?

+1
Los símbolos no son extraños, se usan comúnmente para la lógica en una gran cantidad de lenguajes de programación.
La compatibilidad de copiar y pegar es un argumento muy real, y yo lo apoyo.

Voy a ser el malo y cerrar esta discusión. Esto no se implementará. Me molestan especialmente las declaraciones repetidas sobre el deseo de poder "cortar y pegar comandos de scripts bash". Incluso si fish admitiera operadores && y || , eso no garantizaría que pudiera simplemente cortar y pegar declaraciones que contengan esos operadores. No queremos dar la impresión de que puede hacerlo. Honestamente, si desea la sintaxis y el comportamiento de bash / zsh, debe usar esos shells (o una alternativa que afirme ser compatible con ellos).

La mayoría de las otras ideas discutidas deberían tener sus propios problemas. En particular, puede haber algún mérito en implementar algunos de los comportamientos [[ ... ]] que fueron introducidos por primera vez por ksh88 (no bash). Pero probablemente mejorando el comando incorporado test o un nuevo comando en lugar de implementar esos tokens especiales.

Todavía estoy muy perturbado por esta noción de no admitir zsh y bash. Puedo entender la lógica, pero no estoy de acuerdo con ella. Estaba muy interesado en el pescado hace algún tiempo, pero me alejé debido a esta oposición. Puede haber alguna oportunidad de bifurcar el proyecto aquí si hay suficientes de nosotros, como desarrolladores, a quienes les gustaría ver esto implementado. Es triste ver esta resistencia continua que finalmente impide el impulso y la aceptación de un trabajo tan interesante.

@ylluminate ¿qué tienes en mente al "apoyar a zsh y bash?" ¿Qué nivel de compatibilidad le gustaría ver?

Todavía estoy muy perturbado por esta noción de no admitir zsh y bash. Puedo entender la lógica ...

Me temo que no entiendo su lógica para tener funciones de soporte de peces bash y zsh. Si quieres Java, ¿por qué usar C ++? Si quieres Perl, ¿por qué usar Python? Como acaba de preguntar @ridiculousfish , además de un poco de azúcar sintáctico, ¿qué más tienen que soportar los peces para hacerte feliz? ¿En qué momento el pez se convierte en otro clon de bash?

PD, he estado programando para ganarme la vida desde 1979 y usando UNIX desde mediados de los 80. He usado tantos shells que he perdido la cuenta (por ejemplo, Bourne, Csh, Ksh88, Ksh93, Bash, Zsh, Xonsh). Cambiar de caparazón siempre requiere trabajo (por eso no lo hago más de una vez cada cinco años aproximadamente). Cuando lo hago, no me quejo de que mi nuevo shell no ejecuta todos mis scripts heredados sin cambios.

@ krader1961 Buen discurso. En mi humilde opinión ...

No haría scripts en fish todo el tiempo como (seguido de órdenes):

  1. el guión de fish es lento (más lento que mksh)
  2. alguna sintaxis extraña (por ejemplo, ; and , ; or que se ve feo para mí)
  3. no es compatible con posix (puedo decir que la sintaxis es fácil pero aún necesito tiempo para aprender)

Bueno, no me importaría el 2 y el 3 solo si el script fish es más rápido que otros shells (por ejemplo, mksh, bash).

Por otro lado , utilizo pescado porque:

  1. el tiempo de inicio es más rápido que zsh (pero más lento que bash)
  2. tener muchas funciones habilitadas de forma predeterminada (el resaltado de sintaxis es el mejor)
  3. las configuraciones son agradables y simples (especialmente set -Ux )

@ylluminate Mirando este número de hace cuatro años, puedo ver cuán vagos / ocupados las personas que quieren disfrutar del pescado como bash, todavía son vagos / ocupados. Los ansiosos han estado haciendo su propio caparazón (como magicant / yash, élfico / élfico, michaelmacinnis / oh y yo :-P). Si quieres hacer las cosas de una manera que no sea a pescado, probablemente necesites una cáscara que no sea a pescado.

Si realmente consideras cómo implementar && || en peces y no lo hace muy poco sospechoso, entonces puedes ver que solo estás expulsando begin; end (mira lo que hace el commit 594b460ba2d8dca59a3bfd282397c5f33aa9da6f,contador- ; and or juegan papeles dobles,muy algo feo) y obtener solo un poco de azúcar.

@pickfire ¿Puedes dar más detalles sobre "el guión de

FWIW en mis pruebas, fish es más rápido que bash en general, en virtud de posix_spawn y su analizador rápido, aunque puede ser más lento en ciertos casos como alias .

ivan<strong i="5">@alarmpi</strong> /tmp> echo 'echo test' > script
ivan<strong i="6">@alarmpi</strong> /tmp> time bash script
test
0.02user 0.01system 0:00.03elapsed 96%CPU (0avgtext+0avgdata 2776maxresident)k
0inputs+0outputs (0major+149minor)pagefaults 0swaps
ivan<strong i="7">@alarmpi</strong> /tmp> time mksh script
test
0.00user 0.00system 0:00.02elapsed 0%CPU (0avgtext+0avgdata 1420maxresident)k
480inputs+0outputs (2major+82minor)pagefaults 0swaps
ivan<strong i="8">@alarmpi</strong> /tmp> time fish script
test
0.07user 0.01system 0:00.09elapsed 85%CPU (0avgtext+0avgdata 4204maxresident)k
352inputs+0outputs (2major+231minor)pagefaults 0swaps

@ridiculousfish Imagínense que ya es muy lento en comparación con los demás por solo un echo .

@ krader1961 @ridiculousfish En mi opinión , una vez que https://github.com/fish-shell/fish-shell/issues/2210 se publique, se puede cerrar. Hay una solución muy fácil que @kballard publicó.

@pickfire Gracias por compartir eso. Esa prueba mide la sobrecarga de inicio, no el tiempo de echo . El tiempo de inicio es muy importante, pero no puede sacar conclusiones más allá del tiempo de inicio (que depende principalmente de config.fish) de esa prueba.

Aquí hay un micro benchmark diferente:

> cat test.fish
for i in (seq 1000)
    ls > /dev/null
end

> time fish test.fish
        1.51 real         0.74 user         0.65 sys

> cat test.sh
for i in {1..1000} ; do
    ls > /dev/null
done

> time bash test.sh
        2.01 real         0.85 user         1.12 sys

aquí el pez gana por mucho, pero esto mide principalmente la diferencia de fork vs posix_spawn.

Creo que una conclusión aquí es que necesitamos un conjunto completo de evaluaciones comparativas.

@ridiculousfish Aquí está, el benchmark que me has dado:

> cat test.fish
for i in (seq 1000)
    ls > /dev/null
end
> time fish test.fish
4.18user 4.04system 0:22.62elapsed 36%CPU (0avgtext+0avgdata 4360maxresident)k
96inputs+0outputs (1major+321041minor)pagefaults 0swaps
> cat test.sh
for i in {1..1000} ; do
    ls > /dev/null
done
> time bash test.sh
0.70user 1.62system 0:09.81elapsed 23%CPU (0avgtext+0avgdata 2844maxresident)k
0inputs+0outputs (0major+154100minor)pagefaults 0swaps
> time mksh test.sh
0.00user 0.01system 0:00.04elapsed 24%CPU (0avgtext+0avgdata 1780maxresident)k
752inputs+0outputs (3major+203minor)pagefaults 0swaps

El mksh parece tener una velocidad impresionante.

ls @pickfire fish es una función en Linux que hace algunas otras cosas para hacer que la salida sea más agradable, lo que bash no está haciendo. Si desea una comparación de manzanas con manzanas en Linux, use command ls . (En Darwin, el envoltorio ls del pez es mucho más delgado; debería haberlo señalado, pero lo olvidé).

La explicación de la "velocidad impresionante" de mksh en su prueba es que mksh no tiene expansión de llaves, por lo que solo invoca ls una vez. Obviamente, invocar ls una vez es mucho más rápido que invocarlo 1000 veces.

Esto muestra que la medición del rendimiento es muy complicada: ¡es muy fácil medir algo diferente de lo que cree que está midiendo!

@ridiculousfish , ¿hay alguna razón para usar la función ls script fish se compara con command ls ? El resultado no es importante durante la creación de scripts.

De acuerdo, esta vez hice lo que me dijiste:

> cat test.fish
for i in (seq 1000)
    command ls > /dev/null
end
> time fish test.fish
0.66user 1.04system 0:08.08elapsed 21%CPU (0avgtext+0avgdata 4364maxresident)k
624inputs+0outputs (4major+113176minor)pagefaults 0swaps
> cat test.sh
for i in $(seq 1000) ; do
    ls > /dev/null
done
> time mksh test.sh
0.21user 0.65system 0:07.64elapsed 11%CPU (0avgtext+0avgdata 1884maxresident)k
0inputs+0outputs (0major+119632minor)pagefaults 0swaps
> time bash test.sh
0.15user 1.04system 0:08.66elapsed 13%CPU (0avgtext+0avgdata 2816maxresident)k
0inputs+0outputs (0major+150700minor)pagefaults 0swaps

Al final, mksh sigue siendo el más rápido, ahora me parece impresionante que fish sea ​​más rápido que mksh . Si fish tiene soporte de ejecución de comandos en paralelo incorporado, creo que habría sido el más rápido de todos.

Ese tiempo de usuario de .66 es bastante alto. Supongo que se debe a su contenido de config.fish: definir alias y demás. Para el registro, esto es lo que veo en mi caja de Linux (mejor de 3 para cada uno):

> time fish test.fish
0.15user 1.21system 0:01.33elapsed...
> time mksh test.mksh
0.12user 1.13system 0:01.24elapsed...
> time bash test.sh
0.18user 1.34system 0:01.47elapsed...

todo el mundo está muy cerca.

Puede ser interesante que cualquier punto de referencia incorpore una especie de "shell oracular" que simplemente haga un fork / exec o posix_spawn a algún comando de ruta, para que podamos tener una idea de qué tan lejos estamos de la velocidad máxima que el sistema operativo puede ofrecer. .

@ridiculousfish , mi config.fish es muy corto:

# Solarized colors
test $SHLVL = 2
and sh $HOME/.config/base16-shell/base16-solarized.dark.sh &
set fisher_home ~/.local/share/fisherman
set fisher_config ~/.config/fisherman
source $fisher_home/config.fish

Bueno, porque probablemente usa fisherman , no estoy seguro de si lo ralentizará. @bucaran es el buen tipo para esto. Esta vez, vacié el config.fish (mejor resultado de 5 reintentos):

> time fish test.fish; time mksh test.sh; time bash test.sh
0.62user 1.09system 0:07.28elapsed 23%CPU (0avgtext+0avgdata 4396maxresident)k
0inputs+0outputs (0major+108240minor)pagefaults 0swaps
0.21user 0.62system 0:06.92elapsed 11%CPU (0avgtext+0avgdata 1888maxresident)k
0inputs+0outputs (0major+116674minor)pagefaults 0swaps
0.29user 0.81system 0:07.78elapsed 14%CPU (0avgtext+0avgdata 2780maxresident)k
0inputs+0outputs (0major+145628minor)pagefaults 0swaps

@ridiculousfish @pickfire ¿Puedes chatear en otro tema para que pueda bloquear tus mensajes?

Sí, perdón por enviar spam a este problema. @pickfire si desea hacer un seguimiento de algunos puntos de referencia que cree que son especialmente interesantes o relevantes, no dude en abrir otro número.

Acerca de la compatibilidad de bash y zsh, personalmente no espero una compatibilidad total, pero con cada bit de compatibilidad agregada, fish puede volverse más popular.
Incluso sin tener en cuenta las secuencias de comandos, && y || son importantes porque se utilizan con mucha frecuencia para encadenar comandos. Como ejemplo, todavía tengo problemas con # 2292. Sé que no se puede considerar como un error de los peces, pero el hecho es que mejorar la compatibilidad con los peces lo solucionaría.

Estoy con maxfl aquí,: -1: por tener || y && como parte de la sintaxis fish, si se supone que esto es un voto popular.

Fish no es bash (o zsh). No hay ninguna razón de peso para implementar && y || no sea la compatibilidad con esos shells. La compatibilidad con el statu quo es un objetivo en contra de este proyecto.

@Nodd : Su referencia al problema # 2292 es en realidad un ejemplo de por qué los peces no deberían implementar esa sintaxis. Hacerlo sería otro paso para hacer que la gente piense que el pez es un clon POSIX (bash, zsh, etc.). Eso solo crearía otras demandas de que los peces se comporten como esas conchas en otras áreas.

Para todas las personas que buscan una solución, desde Fish 2.3 puedo confirmar que finalmente hay una solución que funciona completamente.

Simplemente haga lo que menciona la respuesta anterior:

Aqui tienes. Una vez que aterrice el PR # 1633, puede tomar lo siguiente y guardarlo en ~ / .config / fish / functions / fish_user_key_bindings.fish:

function handle_input_bash_conditional --description 'Function used for binding to replace && and ||'
    # This function is expected to be called with a single argument of either & or |
    # The argument indicates which key was pressed to invoke this function
    if begin; commandline --search-mode; or commandline --paging-mode; end
        # search or paging mode; use normal behavior
        commandline -i $argv[1]
        return
    end
    # is our cursor positioned after a '&'/'|'?
    switch (commandline -c)[-1]
    case \*$argv[1]
        # experimentally, `commandline -t` only prints string-type tokens,
        # so it prints nothing for the background operator. We need -c as well
        # so if the cursor is after & in `&wat` it doesn't print "wat".
        if test -z (commandline -c -t)[-1]
            # Ideally we'd just emit a backspace and then insert the text
            # but injected readline functions run after any commandline modifications.
            # So instead we have to build the new commandline
            #
            # NB: We could really use some string manipulation operators and some basic math support.
            # The `math` function is actually a wrawpper around `bc` which is kind of terrible.
            # Instead we're going to use `expr`, which is a bit lighter-weight.

            # get the cursor position
            set -l count (commandline -C)
            # calculate count-1 and count+1 to give to `cut`
            set -l prefix (expr $count - 1)
            set -l suffix (expr $count + 1)
            # cut doesn't like 1-0 so we need to special-case that
            set -l cutlist 1-$prefix,$suffix-
            if test "$prefix" = 0
                set cutlist $suffix-
            end
            commandline (commandline | cut -c $cutlist)
            commandline -C $prefix
            if test $argv[1] = '&'
                commandline -i '; and '
            else
                commandline -i '; or '
            end
            return
        end
    end
    # no special behavior, insert the character
    commandline -i $argv[1]
end

function fish_user_key_bindings
    bind \& 'handle_input_bash_conditional \&'
    bind \| 'handle_input_bash_conditional \|'
end

@Globegitter

¿Qué pasa con solo?

function sudo_bang_bang --on-event fish_postexec
    abbr !! sudo $argv[1]
end

@brj ¿ También poner eso en ~/.config/fish/functions/fish_user_key_bindings.fish ? Eso no pareció funcionar para mí.

Necesita obtener esta función. Entonces, sus opciones son ponerlo en su config.fish o ponerlo dentro de ~ / .conf.d / [name-dont-matter] .fish.

@brj :

@faho lol, tienes razón. Siempre recibo una notificación de ese problema, ¡así que pensé que este era otro caso de sudo!

@Globegitter ¡ Perdón por la confusión!

¿Qué tal enviar la solución alternativa propuesta con pescado como ejemplo, para que los usuarios puedan copiarla cómodamente? El mensaje de error podría ampliarse fácilmente para mencionar esto. Sigo pegando el mismo delineador (de gerrit code-review) donde se usa && porque funciona en casi todos los shells (incluidos Windows cmd.exe además de los shells de Unix-y). Para mí, el script mencionado anteriormente es un refuerzo de productividad (estuve escribiendo bash -c "pegar aquí" durante un tiempo ...).

Como lo hago && ? ¿Existe una resolución?

El mismo problema que el anterior, realmente no puedo encontrar ninguna manera de hacerlo.

gcc test2.c -o a.out && ./a.out

en pescado.

gcc test2.c -o a.out; and ./a.out

@ivan intentó eso, pero da "y" y "./a.out" como argumentos para gcc.

// editar: Por cierto, terminé usando el script bash, porque esto parece ser completamente imposible en fish :(

gcc test2.c -lwlc -o a.out && (( sleep 2s; DISPLAY=:2 xterm ) & ./a.out)

Hago esta cosa "completamente imposible" con bastante frecuencia. ¿Quizás probar la sintaxis ; and en un entorno de peces limpio? Si no funciona, ¿tal vez algo está pasando con el punto y coma? ¿Está escribiendo esto en fish o lo está pasando de otro programa?

@ivan Escribiéndolo .

Perdón por una pregunta probablemente estúpida, pero ¿cómo hago los paréntesis? No puedo encontrar una palabra sobre ellos en la documentación y no es exactamente un tema que se pueda buscar en Google :(

gcc test2.c -lwlc -o a.out && ((dormir 2s; PANTALLA =: 2 xterm) & ./a.out)

@kozec Creo que solo tienes problemas para agrupar tus elementos aquí. Lo que necesita usar es begin como una llave izquierda (así es como yo lo pienso) y end como una derecha.

gcc test2.c -lwlc -o a.out; and begin sleep 2s; env DISPLAY=:2 xterm; end & ./a.out

o sangrado:

      gcc test2.c -lwlc -o a.out
         and begin sleep 2s
             env DISPLAY=:2 xterm
         end & ./a.out

@floam Gracias, eso casi funciona. Pero las cosas anteriores y no se envían a segundo plano :(

Ejemplo mínimo:

begin sleep 2s ; env DISPLAY=:2 xterm ; end & Xephyr :2

duerme 2 s, luego inicia xterm, _entonces_ inicia XServer para ese xterm. xterm ofc se bloquea antes de que XServer esté listo.

Descubrirá que puede solucionarlo de esta manera donde debe, no bonito:

fish -c 'sleep 2s; env DISPLAY=:2 xterm' & Xephyr :2

Cuando tiene una gran cantidad de scripts existentes, para el desarrollo, la construcción y dentro de los scripts de ejecución de npm, no es razonable cambiar, especialmente porque algunos / la mayoría no están en fish. Para los scripts bash regulares con shebang y todo, no es un problema, por supuesto.

Lo bueno (o "bueno") de && es que funciona en los shells regulares no solo en Linux y Mac, sino también en Windows, lo cual es bueno para la configuración rápida de entornos de desarrollo, etc.

No es un factor decisivo de ninguna manera, pero es un poco difícil ver por qué agregarlo sería tampoco.

Bueno, este es un argumento bastante tonto. ¿Por qué no tener diferentes "modos" para el compilador de peces? Es decir, algún tipo de configuración que puede habilitar en el que puede tener cosas de pescado "puro" o puede tener compatibilidad con conchas tipo bash junto con fish-isms. Incluso podría tener diferentes "niveles" de compatibilidad para otros shells para que pueda tener compatibilidad total, sin compatibilidad o algo intermedio. Quiero decir, en un nivel básico, al menos podría implementar algún tipo de compilador de fuente a fuente para esto. O tome el código bash y tradúzcalo a una representación intermedia interna para peces. Podrías hacer todo tipo de cosas para la traducción a este respecto. Corrígeme si me equivoco, pero creo que los conceptos a nivel de lenguaje de bash et al. contra los peces no son tan diferentes en el mundo, ¿verdad?

De todos modos, esos son mis $ 0.02 en este tema que realmente parece una tontería porque se basa en la premisa de:

"pure fish"
XOR
"compatibility with bash / becoming another bash clone"

cuando no hay nada que impida tener puntos intermedios entre estas dos nociones.

Uno debería al menos enfrentar la realidad de que las conchas tipo bash son mucho más estándar y populares que las conchas más esotéricas como el pescado, por lo que realmente debería haber algún tipo de capa de compatibilidad para cualquier posibilidad realista de que los peces se conviertan en una concha que pueda sostenerse. -to-to-toe con bash en términos de estar extendido y no causar problemas de compatibilidad.

... cuando no hay nada que impida tener puntos intermedios entre estas dos nociones.

Nada más que alguien (o grupo de personas) invirtiendo más de 2.000 horas (una persona al año) para escribir el código necesario. Espero revisar las solicitudes de extracción de ti, @ylluminarious , para implementar todo eso. Lo que propones equivale a preguntar por qué alguien no puede hacer que Python también interprete PHP. La respuesta es que, en teoría, podría tener un interruptor de compatibilidad para hacerlo, pero ¿por qué lo haría?

Implementado en # 4620.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

olivergondza picture olivergondza  ·  3Comentarios

gawells picture gawells  ·  3Comentarios

andrewhowdencom picture andrewhowdencom  ·  3Comentarios

krader1961 picture krader1961  ·  3Comentarios

pluckytree picture pluckytree  ·  3Comentarios