Fish-shell: && não funciona

Criado em 19 jun. 2012  ·  98Comentários  ·  Fonte: fish-shell/fish-shell

cd .. && pwd retorna o seguinte erro:

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, posso usar a sintaxe COMMAND; and COMMAND , mas seria bom se fish suportasse isso.

Obrigado!

enhancement

Comentários muito úteis

|| também seria bom.

Todos 98 comentários

|| também seria bom.

Eu só quero expressar uma opinião alternativa.
'||' e '&&' são os elementos de sintaxe, enquanto 'e' e 'ou' são comandos simples. Essa abordagem é simples e limpa.
Acho que não é uma boa ideia introduzir elementos de sintaxe adicionais para implementar recursos já existentes.
É diferente do bash, mas está tudo bem.

Eu também votaria em ter && e || como este é um açúcar sintático comumente usado e seria muito bom ter escrito a usabilidade.

+1 à sugestão de maxfl.

+1 à sugestão de maxfl.

Ruby também tem and e or palavras-chave.

+1

Não tenho nenhuma objeção se alguém quiser fazer isso.

-1 para implementar && / || e +1 para maxfl. E eu realmente não vejo por que deveria ser implementado. Não é açúcar sintático, em bash é apenas a sintaxe e em peixes essa sintaxe não existe. Também seria realmente inútil como açúcar sintático como '; ou' leva exatamente tantas combinações de teclas quanto '||'.

Eu gosto da simplicidade dos comandos and e or , mas um problema é que eles tornam as declarações if estranhas. Por exemplo:

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

comparado com

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

Alguém tem ideias para melhorar isso?

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

Mas embora isso funcione para test builtin, não funciona em nenhum outro lugar. Vamos supor que os builtins a e b devam retornar true para executar c e d . Então, poderíamos escrever assim.

and b
and begin
    c
    d
end

Ou com sintaxe de bloco e if .

if begin
        a
        and b
    end
    c
    d
end

Ou torne condicional aninhado.

if a
    if b
        c
        d
    end
end

Então, novamente, não tenho certeza de quantas vezes esse hack é necessário, mas searchco.de diz que && é usado principalmente com test embutido (ou para efeitos colaterais).

Não tenho certeza se fish precisaria de outra sintaxe útil apenas em casos raros. Já parece [ , exceto que um teve que ficar porque é binário de qualquer maneira (assim como test ). Não parece particularmente suspeito, mas está aqui, porque é binário (ao contrário de [[ que fico feliz que peixes não suportem).

Ter duas sintaxes (ou, neste caso, até três) seria um tanto confuso. Qual sintaxe devo usar?

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

Parece que && é o mais curto, exceto que isso é meia verdade. Digitar ;and leva exatamente o mesmo número de teclas (porque & envolve Shift). Adicionar && encorajaria a adição de sintaxe adicional (mais uma vez, and é analisado de maneira especial, porque você pode inserir palavras-chave como begin depois disso, e elas funcionam).

O problema é que temos as sintaxes ; and e ; or - as novas sintaxes pareceriam duplicatas. Eles já são meio que mágicos (não são apenas uma função de script de shell que verifica a variável $status ), então eu não teria problemas se eles fossem substituídos por && e || .

Não tenho certeza do que pensar. Acho que deveria haver apenas uma sintaxe para fazer isso. Eu gosto de ; and e ; or , mas não teria problemas com && e || , desde que as sintaxes antigas fossem removidas. Mas considerando a compatibilidade com versões anteriores, eu preferiria ficar com ; and e ; or . Talvez se begin fosse mais curto (como colchetes em bash) ... mas isso não pareceria suspeito.

Por que não suportar um builtin [[como o bash faz? Seria mais rápido (veja: eco embutido) e suportaria && e || operadores dentro do [[e]] para emular o comportamento e / ou.

Porque [[ não é um comando real, ele existe apenas no bash. O problema é que [[ é exatamente como [ (principalmente), exceto que possui regras especiais de análise para evitar citações desnecessárias. Veja a lei da ortogonalidade e a lei da descoberta para ver por que não está nos peixes.

Na verdade, tenho quase certeza de que [ não existiria por causa da lei da descoberta e da lei da ortogonalidade, mas existe porque é binário em /usr/bin . test é mais suspeito, porque você pode descobri-lo usando o preenchimento de tabulação. Mas o bloqueio de binários seria bastante arbitrário, então poderia muito bem implementá-lo como integrado.

Por exemplo, em bash [[ cita automaticamente todas as strings.

[[ abc = $variable ]]

Mas isso não é necessário em peixes porque o comportamento de divisão de espaço em branco não existe. Além disso, ele cita automaticamente && , || , < e > porque é um recurso sintático. Em peixes, o && é -a , || é -o . < e > nem mesmo existem.

Ele também tem o operador =~ . Em fish , você pode usar o grep silencioso para isso.

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

Além disso, bash tem < e > operador. Eles verificam qualquer string que seja maior ou menor que a outra string. Isso raramente é útil.

E, ao usar os operadores = e != , você pode usar a sintaxe globing, da mesma forma que usaria as expressões regulares. Novamente, use o grep silencioso para isso.

[[ abc = a* ]]

Além disso, [[ é definido como tendo -e , -nt , -ot , -ef e ! , mas fish já os tem em test embutidos.

Adicionar [[ apenas adicionaria outra palavra-chave, que não seria realmente detectável e não adicionaria realmente muitas funcionalidades. A única funcionalidade interessante é =~ , mas o grep silencioso (ou Perl) pode fazer a mesma coisa, sem adicionar uma nova sintaxe. Além disso, não devemos adicionar tudo ao shell. Não acho que precisamos ter uma expressão regular embutida.

Bem, eu não quis dizer necessariamente que deveríamos reimplementar o [[ builtin do bash, mas, em vez disso, ele deve ser introduzido como uma construção sintática com suas próprias propriedades. Quer dizer, fish compartilha muitas palavras-chave e construções que se parecem com bash's, mas são diferentes, então, não vejo como isso não seria assim.

Embora, com base no que você disse, talvez implementar nosso próprio test seja uma construção melhor, embora, renomeado para algo como cond , como o peixe implementa um math embutido em vez disso de expr . Poderíamos até mesmo ir ao ponto de implementar coisas como <e>, no entanto, usando classificação natural (numérica) em vez de classificação lexicográfica, de modo que funcionasse com números e também com strings.

@Undeterminant builtin [[vs builtin [vs / bin / [diferenças sutis já são confusas no bash; por favor, não vamos piorar a situação adicionando bash - [[vs fish - [[diferenças sutis!
Além disso, o espírito do bash's [[viola a lei da ortogonalidade - ele "fixa" e / ou, mas apenas para condições específicas que o construto suporta.

É irônico que if commands...; then ...; fi do bash admitiria facilmente peixes e / ou entre if...then . Mas não queremos um "então". Talvez a única coisa a corrigir seja tornar o início ... o fim mais fácil.

Aqui está uma ideia estranha (não tenho certeza se gostei):

if (foo; and bar)
  ...
end

Atualmente (...) no início do comando é ilegal; a leitura natural é executar isso e usar a saída como nome do comando, mas exigimos eval para isso.
Se tivermos certeza de que nunca permitiremos essa leitura diretamente, poderíamos redefinir (...) para significar begin ...; end .
Não capturar o stdout nesta posição é inconsistente - mas muito compacto e de aparência limpa.

O que eu odeio nisso é que if (...) implora por outro significado: capture a saída e atribua a ela alguma interpretação booleana. Por exemplo, if (math 2 \< 4) - math não retorna um status, imprime 0 ou 1 no stdout. Um uso importante seria if $saved_bool .
Eu não acho que isso seja prático - não há uma única atribuição correta de significados booleanos para strings, especialmente porque 0/1 são irremediavelmente confusos. Mas quando você encontra pela primeira vez if (...) , parece um palpite razoável.

Para fins de compatibilidade, forneça os operadores comuns encontrados em bash e zsh. Quanto mais fácil se tornar para os novos usuários copiar e colar a maior parte de sua funcionalidade anterior de conchas, melhor será a taxa de absorção dos peixes. Estou descobrindo que, embora eu goste mais de peixes em muitos aspectos, alguns desses pequenos obstáculos tolos estão apenas tornando isso mais um incômodo do que um benefício, ao chegar com mais de 15 anos de personalizações de shell que realmente não deveriam ser um problema de suporte .

Sinceramente, não vejo && como um "pequeno obstáculo bobo". Não seria difícil aprender se você tratasse os peixes como sua própria linguagem, em vez de uma "concha substituta" como o zsh é. Se você leu o tutorial sobre como funciona o peixe do início ao fim, não acho que seja difícil de entender.

Ter algo como command1; and command2 torna mais claro que and é uma execução condicional de command2 e não apenas alguma junção entre command1 e command2 .

Mas @Undeterminante , você não está vendo como a maioria das pessoas vê no início, quando o descobrem, etc. Deixe que esse sentimento ou nível de proficiência venha com o tempo. Por exemplo, eu trouxe centenas de linhas da configuração antiga e, honestamente, não tenho tempo para converter imediatamente tudo o que precisa ser convertido. Estou descobrindo coisas estranhas em que não há nenhum número de linha retornando de peixes sobre onde meu problema está dentro de minhas configurações antigas.

Posso entender sua perspectiva, mas é tendenciosa em relação a alguém que quer fazer a mudança e gostaria de fazer isso ao longo do tempo, em vez de passar por cima de um grande obstáculo. Por favor, não entenda mal, se eu não me importasse com peixes e, portanto, tentasse contribuir, certamente voltaria ao zsh agora. Acho que esse tipo de pensamento e raciocínio é importante para abrir o portão um pouco mais para os recém-chegados.

Então, sim, você está certo sobre a legibilidade, mas vamos deixar o velho funcionar e dar um aviso, em vez de um erro, para desanimar as pessoas.

@ylluminate Você está se enganando. Mesmo que fish suportasse && você ainda não poderia simplesmente usar sua configuração de bash ou zsh, porque há mais diferenças na sintaxe de script do que apenas os operadores lógicos.

Exatamente. fish é funcionalmente diferente, o que significa que você não deve apenas copiar e colar o código diretamente. Se seu código for escrito em bash, a menos que haja uma necessidade explícita de convertê-lo em fish, apenas mantenha-o como bash; são línguas diferentes.

assim
se eu fizer
comando1 && comando2
em peixes, sugere que, em vez disso, eu digito
command1; e command2

Alguém realmente acredita que (na linha de comando) a segunda opção é mais limpa, mais futurística e mais fácil de digitar?

É mais limpo porque se baseia na sintaxe existente para a execução de comandos, em vez de introduzir uma nova sintaxe.

Considere em 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 é o tipo de absurdo que esperamos evitar usando comandos em vez de sintaxe especial.

Essa decisão de design definitivamente incorre em um custo, especialmente em instruções if, que devemos tentar reduzir. Mas devemos abordá-lo de uma posição de "vamos encontrar maneiras de melhorar os peixes dentro de sua filosofia de design", em vez de "vamos encontrar maneiras de tornar os peixes mais parecidos com outras conchas".

Seu código faz o seguinte, certo (assumindo que você pode usar & com blocos)?

foo &
if bar
    baz
end &
qux

Para mim, parece artificial. Além disso, se a sintaxe de & é tão confusa, por que não fazer background embutida ou algo assim?

Eu acho que é de fato um argumento para tornar o plano de fundo um embutido, embora eu não esteja propondo que façamos isso de fato.

O problema com ; and e ; or é que eles interagem mal com os tubos. condition; and echo stuff | grep stuff não funciona, enquanto condition && echo stuff | grep stuff sim. Não vejo outra maneira de contornar esse problema, exceto para adicionar uma sintaxe especial.

and echo stuff | grep stuff parece funcionar para mim. Você pode explicar como está quebrado?

@ridiculousfish é o caso que descobri ao experimentar peixes. A expressão ou é verdadeira fora da declaração if, mas (parece ser?) Falsa quando usada em uma declaração if. A menos que eu esteja faltando alguma coisa aqui?

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

Compare com 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

Nesse caso:

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

poderia ser mais claro se fosse escrito assim:

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

A instrução or está no corpo if! Como os booleanos são comandos, eles não têm precedência especial.

Você pode usar início / fim como "parênteses":

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

Acho que não está relacionado a canais, mas sim à precedência.

Como você pode ver neste bug, há muitas opiniões sobre se peixes devem suportar operadores booleanos :)

então, obrigado pessoal pela energia colocada aqui.

Minha intenção não é trazer a discussão sobre o que é melhor ou não. É apenas uma coisa prática.
Como a maioria de vocês, tenho meus próprios scripts para executar. Mesmo em coisas muito simples, a condição && garante o sucesso do comando (saída 0), enquanto ";" apenas vá em frente sem se importar com o que quer que aconteça. Direito? Portanto, eles não são os mesmos de forma alguma. Espero que todos concordemos nisso. :)

Então, eu tenho meus scripts e nenhum deles funciona com peixes. Sim, eu uso muito &&. Mas isso também acontece com qualquer fragmento de código na rede com bash, geralmente usando && também. Para resumir, a questão é que não posso mais usar meus códigos! : D

Eu estava me perguntando ... É possível estabelecer uma função ou definição no arquivo de configuração do fish para corrigir SOMENTE esse comportamento (significando apenas &&) e voltá-lo como no bash tradicional? É possível? Plausível? Factível?

Mais uma vez, concordo que o uso de "e" pode ser mais agradável, mais claro. Mas não funciona com meu código ou, em geral, com qualquer código bash de iniciante. Então, em vez de mudar o código já escrito substituindo && (... não vai acontecer ... e muito provavelmente não vai funcionar), seria mais fácil permitir que os peixes entendam o bash tradicional se alguém quiser ou precisar, não?

Todos os melhores caras, e obrigado novamente pelo esforço !!

Já nos aproximamos da compatibilidade total com bash / zsh scripts? Desisti de fish acordo com meus comentários anteriores porque não vou perder tempo para converter toda a infraestrutura que já construí em meus ambientes de shell em tantas estações de trabalho e servidores. Adoraria dar outra chance se estivermos mais perto. Caso contrário, continuarei avançando sem ele. Obrigado.

@rhoconlinux Alterar Fish para suportar && não fará seus scripts bash funcionarem. Existem muito mais diferenças do que isso.

Não entendi sua resposta ^ _ ^
É possível definir um alias ou uma função para o problema de &&?

@rhoconlinux Não, você teria que modificar o analisador Fish (em C ++). Meu ponto é, se Fish realmente suportasse && , seus scripts Bash ainda não funcionariam, por causa de todas as outras diferenças entre Fish e Bash.

@kballard ai! hmmm .... Estou tão triste em ouvir isso. Agora eu entendi. Super claro. :)

Obrigado pelo feedback super rápido. Usarei peixes para uma experiência cotidiana mais agradável e irei manter um terminal bash para minhas coisas.

Felicidades! : +1:

Se && for uma preocupação, é fácil lidar com ela.

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

Mas é improvável que essa seja a única coisa que você precisará fazer. O que você quer dizer é uma implementação de # 522.

Eu diria que a principal motivação para && compatibilidade não é a conversão existente
bases de código, mas copiar e colar da Internet.
Por exemplo, vejo algum sudo add-apt-repo... && sudo apt-get update && sudo apt-get install ... snippet, desejo apenas copiar e colar, mas falha.

Isso não é algo que possamos resolver pela educação - sempre haverá
trechos para colar e eles usarão a sintaxe [ba] sh padrão.
E && é de longe o problema nº 1 que estou enfrentando.
( export FOO=bar é # 2, mas pode ser resolvido por function export; set -x -g (echo $argv | sed 's/=/\n/'); end .)

Não é um problema profundo: adquiri o hábito de digitar
bash , colando, Ctrl + D.
Hmm, estou tentado a adicionar um atalho de teclado para executar atual / anterior
linha de comando em bash.

Meus dois centavos sobre o assunto:
Estou trabalhando em uma ferramenta de implantação (https://github.com/andres-montanez/Magallanes) que faz chamadas de comando shell e a maioria dos usuários e colaboradores usará um shell bash. Então, é claro, aqui e ali '&&' são usados ​​para encadear comandos.

Existem soluções alternativas óbvias (como passar todos os comandos explicitamente para o bash)
Mas isso traz uma série de pontos problemáticos. Por um lado, pode haver efeitos colaterais estranhos (ou seja, o PATH e outras variáveis ​​não são definidas da mesma maneira), isso significa hackear algumas partes centrais da ferramenta para esse único propósito, e eu preciso mesclar minhas correções de versão para versão toda vez que eu atualizo.

&& é apenas um dos muitos recursos do bash com os quais o fish não é compatível, mas pode ser o mais básico e amplamente usado. Por exemplo, a ferramenta acima está em PHP, então qualquer coisa complexa é feita em PHP e apenas comandos básicos do sistema são passados ​​para o shell. Encontrar incompatibilidades de sintaxe com um caso de uso mínimo é frustrante.

Eu concordo totalmente com o que @cben disse: && é, na minha opinião, um caso especial porque existem centenas de trechos de código online onde a única diferença entre copiar e colar ou não é o suporte para && .
Embora eu concorde que é importante levar em consideração como os peixes avançam em termos de sintaxe, etc. Eu realmente acho que isso é algo que tornaria a vida de muitos desenvolvedores que usam ou querem usar peixes muito mais fácil. Eu sei que parece uma simples substituição de && por ; and mas é sempre irritante e me deixa um pouco estranho quando digo a outras pessoas como os peixes são incríveis, mas então eu tenho que mexer por aí e mudar algumas palavras-chave, eles geralmente se perguntam por que eu tenho que mudar uma coisa tão simples. Então eu tenho que defender os peixes e isso não é um bom caso para promover os peixes.
Às vezes, são as coisas mais simples que podem ter o maior impacto.
Resumindo, sou totalmente a favor da sintaxe do bash && .

Eu concordo com o que @Globegitter e @cben disseram. Uma grande quantidade de scripts e programas depende de && e || . Eu uso fish shell em minha estação de trabalho e seria bom ter compatibilidade cross-shell ao escrever scripts.

Dado que existem muitas diferenças significativas entre o script Fish e o script Bash, além de apenas && e || , por que todos vocês que comentam aqui acreditam que fazer Fish aceitar && ser de alguma forma significativa? Se você precisar executar um snippet de código Bash, apenas execute bash , execute o snippet e depois saia de volta para Fish.

Acho que muitas pessoas gostariam de se "converter" em peixes, mas têm infraestrutura para trazer. Eu, por exemplo, tenho 15 anos de shell scripts apenas na minha estação de trabalho (sem mencionar outros servidores nos quais gostaria de rodar fish também) que não quero perder tempo convertendo. Não me importo de bisbilhotar e fazer as coisas funcionarem "do jeito do peixe" ao longo de vários meses, mas não há como fazer esse tipo de investimento inicial em meu fluxo de trabalho para mudar para outra concha.

Acredito que peixes teriam um fluxo significativo de usuários se o problema geral de compatibilidade fosse resolvido, mas não parece que isso seja algo prioritário para o projeto pelo que outros que trabalham no desenvolvimento de peixes estão dizendo. Eu mantenho meus olhos nisto exatamente por esta razão, já que eventualmente gostaria de passar para pescar se a paisagem mudar a esse respeito.

Com relação a apenas executar bash ou zsh conforme necessário, isso seria uma quantidade significativa de execução desses shells no meu caso e é simplesmente bobagem seguir este caminho de outra forma.

@kballard Eu tenho um fluxo de trabalho ideal para 95% do script que faço com fish: cmd + C um script muito simples de outra fonte, cmd + tab para iTerm, cmd + v e Enter. Isso é tudo que eu quero fazer, sem bash extra ou qualquer outra coisa, nada mais. Na maioria das vezes, a única coisa que impede esses scripts de trabalharem com esse fluxo de trabalho exato é que há um && presente. Essa é a razão pela qual, para mim e suponho que a maioria dos outros aqui, resolver esse problema seria muito útil.
Se você mesmo não experimenta isso, acredite em mim, isso faz sentido e realmente fica na sua mente se o seu fluxo de trabalho é interrompido com tanta frequência.

Eu amo peixes por tudo o mais e é por isso que eu não pude voltar, mas essa coisa simples é apenas o que impede que seja incrível para mim e presumo que alguns dos outros aqui.

Aqui está. Assim que o PR # 1633 chegar, você pode pegar o seguinte e salvá-lo em ~/.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

Isso vincula & e | e faz com que digitar && ou || traduz automaticamente para o ; and / ; or apropriado command one && command two e faça funcionar.

Observe que até que PR # 1633 seja aceito, este script funcionará para _typing_ && / || mas não para colá-lo.

@kballard Uau, isso é uma ótima notícia! Muito obrigado.

Parece que isso não controla o modo de pesquisa de maneira adequada (não tenho certeza sobre o modo de pager; não estou certo do que exatamente compreende isso). Bater & ou | durante a pesquisa termina a pesquisa. Dito isso, não sei como lidar com isso.

Eu atualizei o script com uma correção de bug para digitar | ou & em um comando de várias linhas.

@kballard Eu vi que o PR foi lançado. Então, o script que você colou acima deve fazer && funcionar com o mestre mais recente?

Sim, deveria. Experimente e me informe se tiver algum problema.

-Kevin

Em 1 de setembro de 2014, à 1h14, Markus Padourek [email protected] escreveu:

@kballard Eu vi que o PR foi lançado. Então, o script que você colou acima deve fazer && funcionar com o master mais recente?

-
Responda a este e-mail diretamente ou visualize-o no GitHub.

Tentei esse script com a nova versão 2.1.1 lançada há alguns dias e não parece funcionar. Terei que esperar até 2.2? Obrigado!

@pragmattica : 2.1.1 foi o lançamento de correção de

@xfix : OK. Obrigado por me avisar. Não posso esperar até 2.2!

INCRÍVEL: +1:

Qualquer changelog em execução disponível? Parece que a raiz CHANGELOG está bastante desatualizada.

@pragmattica Agora que o fish 2.2 foi lançado, eu tentei no ubuntu 14.04 e echo 'test1' && echo 'test2'; transformou em echo test1 &; and echo 'test2';

Pode haver um problema em algum lugar entre fish_user_key_bindings.fish ? (Vou tentar examinar sozinho, mas meu conhecimento de script fish / bash é um pouco instável)

Editar: parece funcionar, entretanto, quando você digita um comando com && . Pode ser um pouco bom se isso acontecer no espaço depois, mas isso não é muito importante. Ótimo, essa metade está funcionando :)

-1 para símbolos estranhos :

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

+1 para símbolos simples :

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

Aaahhh acho que sei qual é o problema @pragmattica o comando commandline retorna o buffer sem aspas. Sim, parece ser isso. Portanto, assim que https://github.com/fish-shell/fish-shell/issues/2210 for corrigido, o script acima também deverá ser corrigido.

Isso ainda é considerado começar?

+1
Os símbolos não são estranhos, eles são comumente usados ​​para lógica em um grande número de linguagens de programação.
A compatibilidade de copiar e colar é um argumento muito real e eu apoio.

Serei o vilão e encerrarei essa discussão. Isso não será implementado. Estou especialmente incomodado com as repetidas declarações sobre querer ser capaz de "recortar e colar comandos de scripts bash". Mesmo que fish suportasse os operadores && e || , isso não garantiria que você pudesse simplesmente recortar e colar instruções contendo esses operadores. Não queremos dar a impressão de que você pode fazer isso. Honestamente, se você deseja a sintaxe e o comportamento do bash / zsh, deve usar esses shells (ou uma alternativa que alega compatibilidade com eles).

A maioria das outras idéias discutidas deve ter seus próprios problemas. Em particular, pode haver algum mérito em implementar alguns dos comportamentos [[ ... ]] que foram introduzidos pela primeira vez por ksh88 (não bash). Mas provavelmente através do aprimoramento do comando test embutido ou de um novo comando, em vez de implementar esses tokens especiais.

Ainda estou muito perturbado com essa noção de não suportar zsh e bash. Posso entender a lógica, mas não concordo com ela. Eu estava muito interessado em peixes há algum tempo, mas me afastei devido a essa oposição. Pode haver alguma oportunidade de bifurcar o projeto aqui se houver um número suficiente de nós, como desenvolvedores, que gostaria de ver isso implementado. É triste ver essa resistência contínua que, em última análise, impede o impulso para a frente e a aceitação de um trabalho tão interessante.

@ylluminate o que você tem em mente ao "apoiar zsh e bash?" Que nível de compatibilidade você gostaria de ver?

Ainda estou muito perturbado com essa noção de não suportar zsh e bash. Eu posso entender a lógica ...

Infelizmente, não entendo sua lógica para ter peixes com suporte a recursos bash e zsh. Se você quer Java, por que usar C ++? Se você quer Perl, por que usar Python? Como o @ridiculousfish acabou de perguntar, além de um pouco de açúcar sintático, o que mais os peixes teriam que suportar para te fazer feliz? Em que ponto o peixe simplesmente se torna outro clone do bash?

PS, eu tenho programado para viver desde 1979 e uso UNIX desde meados dos anos 80. Usei tantos shells que perdi a conta (por exemplo, Bourne, Csh, Ksh88, Ksh93, Bash, Zsh, Xonsh). Trocar conchas sempre requer trabalho (é por isso que não faço isso mais do que uma vez a cada cinco anos ou mais). Quando faço isso, não reclamo que meu novo shell não executa todos os meus scripts legados sem alterações.

@ krader1961 Belo discurso. Em minha humilde opinião ...

Eu não faria scripts em peixes o tempo todo como (seguido por ordens):

  1. o script do fish é lento (mais lento que o mksh)
  2. alguma sintaxe estranha (por exemplo, ; and , ; or que parece feia para mim)
  3. não compatível com posix (posso dizer que a sintaxe é fácil, mas ainda preciso de tempo para aprender)

Bem, eu não me importaria com o 2 e o 3 apenas se o script fish for mais rápido do que outros shells (por exemplo, mksh, bash).

Por outro lado , eu uso peixes porque:

  1. o tempo de inicialização é mais rápido que zsh (mas mais lento que bash)
  2. tem muitos recursos habilitados por padrão (destaque de sintaxe é o melhor)
  3. as configurações são boas e simples (especialmente set -Ux )

@ylluminate Olhando para este problema de quatro anos, posso ver como as pessoas preguiçosas / ocupadas que querem desfrutar de peixes como o bash ainda são preguiçosas / ocupadas. Os ansiosos têm feito sua própria concha (como magicant / yash, élfico / élfico, michaelmacinnis / oh e me :-P). Se você quiser fazer as coisas de uma forma não-peixe, provavelmente precisará de uma concha não-peixe.

Se você realmente considerar como implementar && || em peixes e tornar isso não muito desagradável, então você verá que está apenas expulsando begin; end (veja o que o commit 594b460ba2d8dca59a3bfd282397c5f33aa9da6f faz,counter- ; and or desempenham papéis duplos,muito um pouco feio) e obtenha apenas um pouco de açúcar.

@pickfire Você pode explicar "o script do fish é lento?" Existem testes que o levam a essa conclusão?

FWIW em meus testes, fish é mais rápido do que bash em geral, em virtude de posix_spawn e seu analisador rápido, embora possa ser mais lento em certos 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 Imagine que já é muito lento em comparação com os outros por apenas um echo .

@ krader1961 @ridiculousfish IMO, assim que https://github.com/fish-shell/fish-shell/issues/2210 for liberado, isso pode ser fechado. Existe uma solução muito fácil que @kballard postou.

@pickfire Obrigado por compartilhar isso. Esse teste está medindo a sobrecarga de inicialização, não o tempo de echo . O tempo de inicialização é muito importante, mas você não pode tirar conclusões além do tempo de inicialização (que depende principalmente de config.fish) desse teste.

Aqui está um 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

aqui, fish ganha por muito, mas isso mede principalmente a diferença de fork vs posix_spawn.

Acho que uma conclusão aqui é que precisamos de um conjunto abrangente de benchmarks.

@ridiculousfish Aqui está, a referência que você me deu:

> 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

O mksh parece ter uma velocidade impressionante.

ls @pickfire fish é uma função no Linux que faz algumas outras coisas para tornar a saída mais agradável, o que o bash não está fazendo. Se você quiser uma comparação exata no Linux, use command ls . (Em Darwin, o envoltório de ls do peixe é muito mais fino - eu deveria ter apontado isso, mas esqueci.)

A explicação para a "velocidade impressionante" do mksh em seu teste é que o mksh não tem expansão de chave, então ele só invoca ls uma vez. Obviamente, invocar ls uma vez é muito mais rápido do que invocá-lo 1000 vezes.

Isso mostra que a medição de desempenho é muito complicada - é muito fácil medir algo diferente do que você pensa que está medindo!

@ridiculousfish , há alguma razão para usar a função ls se o script fish for comparado a command ls ? A saída não é importante durante o script.

Ok, desta vez eu fiz o que você disse:

> 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

No final, mksh ainda é o mais rápido, agora acho impressionante que fish seja mais rápido do que mksh . Se fish tivesse suporte integrado para execução de comandos paralelos, acho que teria sido o mais rápido de todos.

Esse tempo de usuário de 0,66 é bastante alto. Eu especulo que é devido ao conteúdo do seu config.fish - definindo apelidos e tal. Para registro, isto é o que vejo na minha caixa Linux (melhor de 3 para cada):

> 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...

todos estão muito próximos.

Pode ser interessante para qualquer benchmark incorporar uma espécie de "shell oracular" que apenas executa um fork / exec ou posix_spawn para algum comando de caminho, para que possamos ter uma noção de quão longe estamos da velocidade máxima que o sistema operacional pode oferecer .

@ridiculousfish , meu config.fish é muito curto:

# 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

Bem, porque provavelmente ele usa fisherman , não tenho certeza se ele irá desacelerá-lo. @bucaran é o cara legal para isso. Desta vez, esvaziei config.fish (melhor resultado de 5 tentativas):

> 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 Você pode conversar sobre outro assunto para que eu possa bloquear suas mensagens?

Sim, desculpe por enviar spam para este problema. @pickfire se você gostaria de acompanhar alguns benchmarks que você considera especialmente interessantes ou relevantes, sinta-se à vontade para abrir outra edição.

Sobre compatibilidade bash e zsh, eu pessoalmente não espero uma compatibilidade total, mas com cada bit de compatibilidade adicionado, fish pode se tornar mais popular.
Mesmo sem levar o script em consideração, && e || são importantes porque são comumente usados ​​para encadear comandos. Por exemplo, ainda tenho problemas com o # 2292. Eu sei que não pode ser considerado um bug de peixe, mas o fato é que melhorar a compatibilidade de peixe resolveria isso.

Estou com o maxfl aqui,: -1: por ter || e && como parte da sintaxe fish, se isso for suposto ser um voto popular.

O peixe não é bash (ou zsh). Não há nenhuma razão convincente para implementar && e || não ser para compatibilidade com esses shells. A compatibilidade com o status quo é um anti-objetivo deste projeto.

@Nodd : Sua referência ao problema # 2292 é na verdade um exemplo de por que fish não deveria implementar essa sintaxe. Fazer isso seria mais um passo para fazer as pessoas pensarem que o peixe é um clone do POSIX (bash, zsh, etc.). Isso apenas criaria outras demandas de que os peixes se comportassem como as conchas em outras áreas.

Para todas as pessoas que procuram uma solução, desde o fish 2.3 posso confirmar que finalmente existe uma solução totalmente funcional.

Faça apenas o que a resposta acima menciona:

Aqui está. Assim que o PR # 1633 chegar, você pode pegar o seguinte e salvá-lo em ~ / .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

Que tal apenas?

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

@brj Também colocando isso em ~/.config/fish/functions/fish_user_key_bindings.fish ? Isso não pareceu funcionar para mim.

Você precisa obter esta função. Portanto, suas opções são colocá-lo em seu config.fish ou colocá-lo dentro de ~ / .conf.d / [name-dont-matter] .fish.

@brj :

@faho lol, você está certo. Sempre recebo uma notificação desse problema, então pensei que esse fosse mais um caso de sudo !!.

@Globegitter Desculpem a confusão!

Que tal enviar a solução proposta com peixes como exemplo, para que os usuários possam copiá-la convenientemente? A mensagem de erro pode ser facilmente aumentada para mencionar isso. Eu continuo colando o mesmo liner (da revisão de código gerrit) onde && é usado porque funciona em quase todos os shells (incluindo windows cmd.exe além de shells unix-y). Para mim, o script mencionado acima é um impulsionador da produtividade (eu estava digitando bash -c "colar aqui" por um tempo ...).

Como eu faço && ? Existe uma resolução?

Mesmo problema acima, eu realmente não consigo encontrar nenhuma maneira de fazer

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

em peixes.

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

@ivan tentou isso, mas fornece "e" e "./a.out" como argumentos para o gcc.

// editar: a propósito, acabei usando o script bash, porque isso parece ser completamente impossível em peixes :(

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

Eu faço essa coisa "completamente impossível" com bastante frequência. Talvez tente a sintaxe ; and em um ambiente de peixes limpo? Se não funcionar, talvez algo esteja errado com seu ponto-e-vírgula? Você está digitando isso no fish ou está sendo transmitido de outro programa?

@ivan Digitando.

Desculpe pela pergunta provavelmente estúpida, mas como faço para colocar parênteses? Não consigo encontrar uma palavra sobre eles na documentação e não é exatamente um tópico que pode ser acessado no Google :(

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

@kozec Acho que você está apenas tendo problemas para agrupar seus itens aqui. O que você precisa usar é begin como uma chave esquerda (é assim que penso) e end como uma direita.

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

ou recuado:

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

@floam Obrigado, isso quase funciona. Mas as coisas antes e não são enviadas para segundo plano :(

Exemplo mínimo:

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

dorme 2s, então inicia o xterm, _então_ inicia o XServer para aquele xterm. O xterm ofc trava antes que o XServer fique pronto.

Você vai descobrir que pode contornar isso fazendo isso onde você deve, não bonito:

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

Quando você tem uma grande quantidade de scripts existentes, para desenvolvimento, construção e dentro dos scripts de execução do npm, não é razoável mudar, especialmente porque alguns / a maioria não estão no fish. Para os scripts bash regulares com shebang e tudo isso não é um problema, é claro.

O bom (ou "legal") do && é que ele funciona nos shells normais não apenas do Linux e Macs, mas também do Windows, o que é bom para uma configuração rápida de ambientes de desenvolvimento, etc.

Não é um problema, de forma alguma, mas é meio difícil de entender por que adicioná-lo também seria?

Bem, este é um argumento bastante bobo de se ter. Por que não ter "modos" diferentes para o compilador fish? Ou seja, algum tipo de configuração que você pode ativar, em que pode ter coisas de peixe "puras" ou pode ter compatibilidade com conchas semelhantes a bash junto com ismos de peixe. Você pode até ter diferentes "níveis" de compatibilidade para outros shells, de modo que possa ter compatibilidade total, sem compatibilidade ou algo intermediário. Quer dizer, em um nível básico, você poderia pelo menos implementar algum tipo de compilador de código-fonte para isso. Ou pegue o código bash e traduza-o em uma representação interna intermediária para peixes. Você poderia fazer todos os tipos de coisas para tradução nesse sentido. Corrija-me se eu estiver errado, mas acredito que os conceitos de nível de linguagem de bash et al. e os peixes não são totalmente diferentes, certo?

De qualquer forma, esse é meu US $ 0,02 nessa questão que realmente parece bobo porque é baseado na premissa de:

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

quando não há nada que impeça o (s) meio (s) meio (s) entre essas duas noções.

Deve-se pelo menos encarar a realidade de que conchas semelhantes a bash são muito mais padronizadas e populares do que conchas mais esotéricas como peixes, então deve haver algum tipo de camada de compatibilidade para qualquer chance realista de o peixe se tornar uma concha capaz de suportar os dedos do pé -to-toe com bash em termos de ser generalizado e não causar dores de cabeça de compatibilidade.

... quando não há nada que impeça o (s) meio (s) meio (s) entre essas duas noções.

Nada além de alguém (ou grupo de pessoas) investindo mais de 2.000 horas (uma pessoa por ano) para escrever o código necessário. Estou ansioso para revisar as solicitações de pull de você, @ylluminarious , para implementar tudo isso. O que você está propondo é equivalente a perguntar por que alguém não pode fazer Python também interpretar PHP. A resposta é que teoricamente você poderia ter um switch de compatibilidade para fazer isso, mas por que teria?

Implementado em # 4620.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

luc-j-bourhis picture luc-j-bourhis  ·  3Comentários

rwz picture rwz  ·  3Comentários

krader1961 picture krader1961  ·  3Comentários

zx8 picture zx8  ·  3Comentários

badp picture badp  ·  3Comentários