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 / 453144
Accepted
Tom Hale
Tom Hale
Asked: 2018-07-03 21:04:22 +0800 CST2018-07-03 21:04:22 +0800 CST 2018-07-03 21:04:22 +0800 CST

contexto de chamada da função em zsh: equivalente de bash `caller`

  • 772

No bash, posso escrever:

caller 0

e receba o contexto do chamador :

  • Número da linha
  • Função
  • Nome do script

Isso é extremamente útil para depuração. Dado:

yelp () { caller 0; }

Eu posso então escrever yelppara ver quais linhas de código estão sendo alcançadas.

Eu posso implementar caller 0em bashcomo:

echo "${BASH_LINENO[0]} ${FUNCNAME[1]} ${BASH_SOURCE[1]"

Como posso obter a mesma saída que caller 0em zsh?

zsh shell
  • 2 2 respostas
  • 2170 Views

2 respostas

  • Voted
  1. Best Answer
    muru
    2018-07-03T21:42:50+08:002018-07-03T21:42:50+08:00

    Eu não acho que haja um comando embutido equivalente, mas alguma combinação dessas quatro variáveis ​​do módulo zsh/Parameter pode ser usada:

    funcfiletrace
    

    Essa matriz contém os números absolutos de linha e os nomes de arquivo correspondentes para o ponto em que a função atual, arquivo de origem ou comando (se EVAL_LINENOestiver definido) foi chamado. evalA matriz tem o mesmo comprimento que funcsourcetracee functrace, mas difere de funcsourcetraceque a linha e o arquivo são o ponto de chamada, não o ponto de definição, e difere de functraceque todos os valores são números de linha absolutos em arquivos, em vez de relativos ao início de uma função, se houver.

    funcsourcetrace
    

    Esta matriz contém os nomes de arquivo e números de linha dos pontos onde as funções, arquivos de origem e (se EVAL_LINENOestiver definido) eval comandos que estão sendo executados atualmente foram definidos. O número da linha é a linha onde o ' function name' ou ' name ()' começou. No caso de uma função carregada automaticamente, o número da linha é relatado como zero. O formato de cada elemento é filename:lineno.

    Para funções carregadas automaticamente de um arquivo no formato zsh nativo, onde apenas o corpo da função ocorre no arquivo, ou para arquivos que foram executados pelos sourceou ' .' builtins, as informações de rastreamento são mostradas como filename:0, pois o arquivo inteiro é o definição. O nome do arquivo de origem é resolvido para um caminho absoluto quando a função é carregada ou o caminho para ela é resolvido de outra forma.

    A maioria dos usuários estará interessada nas informações da funcfiletracematriz.

    funcstack
    

    Essa matriz contém os nomes das funções, arquivos de origem e comandos (se EVAL_LINENOestiver definido) . evalatualmente em execução. O primeiro elemento é o nome da função usando o parâmetro.

    O array de shell padrão zsh_eval_contextpode ser usado para determinar o tipo de construção de shell que está sendo executada em cada profundidade: observe, no entanto, que está na ordem oposta, com o item mais recente por último, e é mais detalhado, por exemplo, incluindo uma entrada para toplevel, o código principal do shell sendo executado interativamente ou a partir de um script, que não está presente no $funcstack.

    functrace
    

    Essa matriz contém os nomes e números de linha dos chamadores correspondentes às funções que estão sendo executadas no momento. O formato de cada elemento é name:lineno. Os chamadores também são mostrados para arquivos de origem; o chamador é o ponto onde o comando sourceou ' .' foi executado.

    Comparando:

    foo.bash:

    #! /bin/bash
    yelp() {
        caller 0
    }
    
    foo () {
        yelp
    }
    
    foo
    

    foo.zsh:

    #! /bin/zsh
    yelp() {
        print -l -- $funcfiletrace - $funcsourcetrace - $funcstack - $functrace
    }
    
    foo () {
        yelp
    }
    
    foo
    

    Os resultados:

    $ bash foo.bash
    7 foo foo.bash
    
    $ zsh foo.zsh
    foo.zsh:7
    foo.zsh:10
    -
    foo.zsh:2
    foo.zsh:6
    -
    yelp
    foo
    -
    foo:1
    foo.zsh:10
    

    Assim, os valores correspondentes estão em ${funcfiletrace[1]}e ${funcstack[-1]}. Modificando yelppara:

    yelp() {
        print -- $funcfiletrace[1] $funcstack[-1]
    }
    

    A saída é:

    foo.zsh:7 foo
    

    que é bem próximo do bash

    7 foo foo.bash
    
    • 21
  2. Tom Hale
    2018-07-03T23:42:39+08:002018-07-03T23:42:39+08:00

    Com base na resposta de muru , implementei a seguinte função que funciona em ambos {ba,z}sh:

    $ cat yelp
    #!/bin/zsh
    # Say the file, line number and optional message for debugging
    # Inspired by bash's `caller` builtin
    # Thanks to https://unix.stackexchange.com/a/453153/143394
    function yelp () {
      # shellcheck disable=SC2154  # undeclared zsh variables in bash
      if [[ $BASH_VERSION ]]; then
        local file=${BASH_SOURCE[1]} func=${FUNCNAME[1]} line=${BASH_LINENO[0]}
      else  # zsh
        emulate -L zsh  # because we may be sourced by zsh `emulate bash -c`
        # $funcfiletrace has format:  file:line
        local file=${funcfiletrace[1]%:*} line=${funcfiletrace[1]##*:}
        local func=${funcstack[2]}
        [[ $func =~ / ]] && func=source  # $func may be filename. Use bash behaviour
      fi
      echo "${file##*/}:$func:$line $*" > /dev/tty
    }
    
    foo () { yelp; }
    yelp
    foo
    

    A saída é:

    $ ./yelp
    yelp::20 
    yelp:foo:19
    
    • 3

relate perguntas

  • Como funciona este comando? mkfifo /tmp/f; cat /tmp/f | /bin/sh -i 2>&1 | nc -l 1234 > /tmp/f

  • FreeBSD's sh: funções de lista

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • o que grep -v grep faz

  • Como salvar um caminho com ~ em uma variável?

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