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 / coding / Perguntas / 79188872
Accepted
Jared Frazier
Jared Frazier
Asked: 2024-11-14 21:05:18 +0800 CST2024-11-14 21:05:18 +0800 CST 2024-11-14 21:05:18 +0800 CST

Imprimindo o corpo da função bash e incluindo os comentários no corpo

  • 772

Estou usando shdoc para gerar arquivos markdown para minhas funções bash; no entanto, gostaria de anexar também o corpo da função bash associada , bem como os comentários nesse corpo, ao arquivo markdown gerado por shdoc. Como posso imprimir um corpo de função bash e, ao mesmo tempo, incluir os comentários no corpo da função?

Como um exemplo simples, considere que todos os meus arquivos bash estão contidos em um diretório chamado srce todos esses arquivos terminam em .sh. A função abaixo no arquivosrc/foo.sh

# @description A function that does something
foo() {
  # oh wow, a comment
  echo "something cool"
}

Agora, se eu quiser obter o corpo da função sem comentários, posso fazer isso facilmente, declare -fconforme mostrado abaixo, em um arquivo chamado src/doc.sh:

# assuming you are in the `src` dir and both .sh files are executable
. foo.sh
foo_doc=$(declare -f foo)
echo "$foo_doc"

Mas o problema é foo_docque só tem a função body, já queecho "$foo_doc"

foo () 
{ 
    echo "something cool"
}

e nenhum comentário. Então, se eu fosse anexar essas informações a um markdown gerado por shdoc, não seria uma documentação ideal do código-fonte.

Acho que uma abordagem seria usar sedpara determinar as linhas correspondentes à função de interesse (minhas funções bash são "delimitadas" por {e }, embora, pelos comentários, eu entenda que há outras maneiras de declarar funções bash válidas), então eu poderia usar sedpara obter apenas essas linhas, como feito aqui .

bash
  • 2 2 respostas
  • 73 Views

2 respostas

  • Voted
  1. Verpous
    2024-11-14T21:55:10+08:002024-11-14T21:55:10+08:00

    É um pouco complicado, mas você pode usar comentários com dois pontos:

    foo() {
        : This is a comment
        echo foo this bar
    }
    

    Explicação: :em bash é um comando no-op. Você pode passar a ele quaisquer argumentos que quiser, e ele os ignora. Então esse "comentário" é, na verdade, tecnicamente um comando que faz parte do corpo da função que não faz nada. Você tem que ter cuidado, porém, se seus comentários incluírem caracteres especiais, você terá que colocá-los entre aspas.

    • 2
  2. Best Answer
    Ed Morton
    2024-11-15T00:08:41+08:002024-11-15T00:08:41+08:00

    Como você tem acesso aos arquivos que contêm as definições de função, você pode fazer isso com qualquer awk POSIX:

    awk '
        /^[[:alpha:]_][[:alnum:]_]*[[:space:]]*\(/ && ($1 !~ /^(if|elif|for|while|until)$/) {
            inFunc = 1
        }
        inFunc {
            print
            if ( /^[})]/ ) {
                inFunc = 0
            }
        }
    ' src/*.sh
    

    Não é 100% robusto, mas provavelmente será bom o suficiente para suas funções se elas se parecerem com o exemplo que você forneceu (ou seja, começar com alphanumeric_name (no início de uma linha e terminar com }ou )no início de uma linha) e você não tiver nenhum outro código em seus scripts que também se pareça com isso, mas não seja uma definição de função.

    Adicione mais palavras-chave ao $1 !~teste, se desejar, ou você pode torná-lo mais robusto adicionando uma chamada declare -Fe aceitando somente definições de função aparentes correspondidas pela expressão regular acima se a string corresponder a uma definição de função real, conforme relatado por declare -F.

    Por exemplo:

    $ cat src/tst.sh
    # The following is a function
    # that does amazing things.
    foo() {
      # oh wow, a comment
      echo "something cool"
    }
    
    # other code
    if (( $# > 1 )); then
        echo "Eureka"
    fi
    
    # This function, however, is
    # useless, can't believe we
    # bothered to write it.
    bar() {
      # this sucks
      # hope it doesn't get called
      echo "the sky is falling"
    }
    

    $ . src/tst.sh
    

    $ declare -f foo bar
    foo ()
    {
        echo "something cool"
    }
    bar ()
    {
        echo "the sky is falling"
    }
    

    $ declare -F foo bar
    foo
    bar
    

    $ declare -F |
    awk '
        NR == FNR {
            funcs[$3]
            next
        }
        /^[[:alpha:]_][[:alnum:]_]*[[:space:]]*\(/ && ($1 in funcs) {
            inFunc = 1
        }
        inFunc {
            print
            if ( /^[})]/ ) {
                inFunc = 0
            }
        }
    ' - FS='[[:space:](]+' src/*.sh
    foo() {
      # oh wow, a comment
      echo "something cool"
    }
    bar() {
      # this sucks
      # hope it doesn't get called
      echo "the sky is falling"
    }
    

    e se você quiser obter comentários que terminem na linha imediatamente antes de cada função também:

    $ declare -F |
    awk '
        NR == FNR {
            funcs[$3]
            next
        }
        /^[[:alpha:]_][[:alnum:]_]*[[:space:]]*\(/ && ($1 in funcs) {
            printf "%s", cmt
            inFunc = 1
        }
        { cmt = (/^#/ ? cmt $0 ORS : "") }
        inFunc {
            print
            if ( /^[})]/ ) {
                print ""
                inFunc = 0
            }
        }
    ' - FS='[[:space:](]+' src/*.sh
    # The following is a function
    # that does amazing things.
    foo() {
      # oh wow, a comment
      echo "something cool"
    }
    
    # This function, however, is
    # useless, can't believe we
    # bothered to write it.
    bar() {
      # this sucks
      # hope it doesn't get called
      echo "the sky is falling"
    }
    

    Observe que isso imprimirá apenas as funções definidas em seus arquivos e que estão disponíveis em seu ambiente, diferentemente do primeiro script, que imprimirá todas as funções em seus arquivos.

    • 2

relate perguntas

  • (macOS Bash) 2 strings aparentemente idênticas não são iguais, mostrando apenas diferenças com "set -x"

  • Xargs: a substituição do alias falha apesar de expandir o alias

  • Diferença entre $PATH e ${PATH:+:${PATH}} em ambientes Linux

  • awk localize e substitua por regex e variável de ambiente

  • Como preencher nomes de arquivo com zeros de strings alfanuméricas numeradas e delimitadas de comprimento arbitrário no bash?

Sidebar

Stats

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

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

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