AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 443507
Accepted
Саша Черных
Саша Черных
Asked: 2018-05-13 23:23:10 +0800 CST2018-05-13 23:23:10 +0800 CST 2018-05-13 23:23:10 +0800 CST

Por que preciso colocar “do” na mesma linha que “for”?

  • 772

1. Resumo

Não entendo, por que preciso da regra bashate E010 .


2. Detalhes

Eu uso bashate para .sharquivos linting. Regra E010:

não na mesma linha que para

forbashar:

  • Correto:

    #!/bin/bash
    for f in bash/*.sh; do
        sashacommand "$f"
    done
    
  • Erro:

    #!/bin/bash
    for f in bash/*.sh
        do sashacommand "$f"
    done
    

Existe algum argumento válido, por que preciso fore dona mesma linha?


3. Não é útil

Não consigo encontrar uma resposta para minha pergunta em:

  1. Google
  2. Artigos sobre as melhores práticas de codificação ( exemplo )
  3. documentação do bashate . encontro apenas :

    Um conjunto de regras que ajudam a manter as coisas consistentes nos blocos de controle. Estes são ignorados em linhas longas que têm uma continuação, porque desenrolar isso é meio “interessante”

bash shell-script
  • 5 5 respostas
  • 6953 Views

5 respostas

  • Voted
  1. Best Answer
    Kusalananda
    2018-05-13T23:32:37+08:002018-05-13T23:32:37+08:00

    Sintaticamente, os dois trechos de código a seguir são corretos e equivalentes:

    for f in bash/*.sh; do
        sashacommand "$f"
    done
    
    for f in bash/*.sh
        do sashacommand "$f"
    done
    

    Pode-se dizer que o último é mais difícil de ler, pois doofusca ligeiramente o comando no corpo do loop. Se o loop contiver vários comandos e o próximo comando estiver em uma nova linha, a ofuscação será ainda mais destacada:

    for f in *
        do cmd1
        cmd2
    done
    

    ... mas sinalizá-lo como um "erro" é IMHO a opinião pessoal de alguém, e não uma verdade objetiva.

    Eu diria que se você quiser preceder o comando no loop com do, sinta-se à vontade para fazê-lo se isso tornar o código consistente e legível aos olhos de quem estiver lendo o código.

    Em geral, quase qualquer um ;pode ser substituído por uma nova linha. Ambos ;e nova linha são terminadores de comando. doé uma palavra-chave que significa "aqui segue o que precisa ser feito (neste forloop)".

    for f in *; do ...; done
    

    é o mesmo que

    for f in *
    do
       ...
    done
    

    e como

    for f in *; do
       ...
    done
    

    e

    for f in *
       do ...
    done
    

    A razão para usar um sobre o outro é a legibilidade e as convenções de estilo locais/pessoais.


    Opinião pessoal:

    Em cabeçalhos de loop muito longos , acho que pode fazer sentido colocar douma nova linha, como em

    for i in animals people houses thoughts basketballs bees
    do
        ...
    done
    

    ou

    for i in        \
        animals     \
        people      \
        houses      \
        thoughts    \
        basketballs \
        bees
    do
        ...
    done
    

    O mesmo vale para o thenem uma ifdeclaração.

    Mas, novamente, isso se resume às preferências de estilo pessoal ou a qualquer estilo de codificação que a equipe/projeto esteja usando.

    • 62
  2. ilkkachu
    2018-05-14T00:59:08+08:002018-05-14T00:59:08+08:00

    Observe o que diz no topo da página:

    bashate: Um equivalente pep8 para scripts bash

    PEP8 é o Guia de Estilo para Código Python. Embora o pessoal do Python geralmente pareça levar seus problemas de estilo muito a sério [citação necessária] , é apenas isso, um guia. Poderíamos apresentar vantagens tanto para colocar o dona mesma linha que o for, quanto para colocá-lo em uma linha própria.

    É a mesma discussão de onde colocar o {código C ao iniciar um bloco ou (ou algo parecido) if.while


    Algumas linhas abaixo na documentação, há outra regra interessante:

    E020: Declaração de função fora do formato^function name {$

    Presumo que o ponto aqui é que o autor desse guia de estilo pensa que usar a functionpalavra-chave é necessário para que o leitor reconheça uma declaração de função. No entanto, function fooé uma forma não padronizada de definir uma função: a forma padrão é foo(). A única diferença entre os dois (no Bash) é que o outro é mais difícil de portar para um shell padrão, como /bin/shno Debian ou no Ubuntu.

    Então, eu sugeriria pegar todos e quaisquer guias de estilo com um grão de sal ou três e decidir por si mesmo qual é o melhor estilo. Um bom verificador de estilo permite desabilitar algumas verificações (bashate tem bashate -i E010,E011que ignorar essas duas verificações). Um excelente verificador de estilo permitiria que você modificasse os testes, por exemplo, para verificar o oposto de E020, aqui.

    • 29
  3. alexis
    2018-05-14T06:47:55+08:002018-05-14T06:47:55+08:00

    TL;DR: Você não precisa. É só a opinião de um cara.

    Como muitos outros, escrevo forloops como este há décadas:

    for F in arg1 arg2 arg*
    do
        somecommand "$F"
    done
    

    Esse layout destaca o fato de do ... doneenvolver o corpo do loop, como chaves em linguagens semelhantes a C, e permite que novas linhas separem os componentes da construção do loop.

    É claro que também existem guerras religiosas sobre onde colocar as chaves, então você pode dizer que o júri ainda não decidiu. IMHO, é claramente assim que isso foi projetado para funcionar; Bourne gostava de delimitadores combinados, cf. if ... fi, case ... esac, e a necessidade de um ponto e vírgula na versão mais curta revela que você está tornando-a mais curta do que originalmente projetada. Nada de errado com isso; avanços tecnológicos e muitas coisas que antes pareciam uma boa ideia agora são desaprovadas, como goto. Mas até que toda a comunidade de scripts de shell adote as preferências do bashate(s) autor(es), você não precisa fazer nada.

    • 14
  4. user56373
    2018-05-15T16:35:46+08:002018-05-15T16:35:46+08:00

    Várias boas respostas aqui. Sempre tome guias de estilo com um pouco de sal, e IMHO e experiência, esteja sempre tão leve a moderadamente preocupado com qualquer comunidade que esteja repleta de dogmas excessivos quando se trata de estilo. É quase como se eles acreditassem que, quando FINALMENTE conseguirem o último ponto pontilhado e o último T cruzado, o software funcionará. Às vezes é preciso mais do que um estilo perfeito para remover bugs...

    Quando comecei a aprender shell, a maioria dos scripts e tutes usavam o formato de ponto e vírgula in-line

    for i in "$@"; do
        stuff
    done
    

    mas como eu era inexperiente, tive um pouco de dificuldade em identificar o ; e fazer - ambos essenciais para confirmar a correção sintática. Então eu preferi o do na próxima linha sozinho. Eu não faço mais isso (trocadilho intencional)

    Além disso, o comando 'while' é um excelente candidato para um pequeno truque:

    while prep1; prep2; condition; do
        stuff
    done
    

    mas quando os comandos prep são um pouco volumosos e/ou a condição é complexa, é melhor formatá-los como

    while
        prep1
        prep2
        condition
    do
        stuff
    done
    

    e, em seguida, anexar o do como "; do" é positivamente fútil.

    Você pode até ficar mais intenso do que isso:

    while
        if con1; then
          cond2
        elif cond3; then
          cond4
        elif cond5; then
          cond6
        else
          cond7
        fi
    do
        stuff
    done
    

    porque cada declaração é uma expressão. Observe como ambos os estilos são usados ​​de forma oportunista. Mantenha-o limpo e é bastante legível. Compacte ou contorça em nome do estilo ou "economize espaço" e torna-se uma bagunça horrível.

    Então! Dado o estilo bastante barroco dos scripts de shell em geral, qualquer coisa destinada a aumentar a clareza e facilitar o acesso visual a símbolos significativos é sempre uma coisa boa.

    A forma em que 'do' é escrito em linha com o comando é agradável quando você tem um pequeno comando - não acho o 'do' visualmente oculto, nem o comando interno é realmente obscurecido:

    for i in whatever
      do stuff
    done
    

    Acho isso bastante agradável de se ver e tem análogos com while, if e case:

    while condition
      do stuff
    end
    
    if condition
      then stuff1
      else stuff2
    fi
    
    case $blah in
      a) stuff1;;
      b) stuff2;;
      c) stuff3;;
      *) stuffInfinity;;
    esac
    

    Clareza e organização geral é tudo o que Codd* pede de você.

    *Edgar F. Codd, pai da teoria de banco de dados relacional.

    • 4
  5. Zombo
    2018-05-14T14:04:50+08:002018-05-14T14:04:50+08:00

    Estou surpreso que ninguém tenha mencionado essa sintaxe válida e portátil ainda:

    set alfa bravo charlie
    for q do
      echo "$q"
    done
    

    Observe cuidadosamente que fore doestão na mesma linha, sem ponto e vírgula. Resultado:

    alfa
    bravo
    charlie
    
    • 3

relate perguntas

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • MySQL Select com função IN () com array bash

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve