Onde as funções do shell são armazenadas no Linux?

11

No começo eu estava procurando o motivo que whichnão produzia nada depois de dar certos programas como um argumento, por exemplo cd.

Pelo que eu encontrei aqui , a razão provavelmente é que cdna minha máquina é uma função, que é confirmada pela execução type cd.

TLDR: Mas como programas normais que whichpodem localizar graças a $PATHvariáveis ​​são colocados em uma dessas $PATHpastas, onde estão as funções ou scripts como cdarmazenados?

user@linuxmchine:~$ type cd
cd is a function
cd () 
{ 
    __zsh_like_cd cd "$@"
}
Gabrijel Šimunović
fonte
Eu fico cd is a shell builtin. Dê uma olhada na página man do seu shell (zsh?)
Xen2050
1
Check out unix.stackexchange.com/questions/85249/… O problema é que é um comando legado que não deve ser usado - especialmente por causa de coisas como essa questão.
Joe

Respostas:

12

Funções definidas pelo usuário

Normalmente, as funções bash são permanentemente armazenadas em um bashscript de inicialização.

  • Scripts de inicialização de todo o sistema: /etc/profilepara shells de login e /etc/bashrcpara shells interativos.
  • O usuário define os scripts de inicialização: ~/.bash_profilepara shells de login e ~/.bashrcpara shells interativos.
  • Mais informações sobre shells interativos / de login podem ser encontradas na manpágina bash da seção INVOCATION.

As funções de shell definidas pelo usuário são carregadas dinamicamente em um hash (ou tabela de consulta) quando o bash é iniciado. No arquivo de origem do bash, variable.ca definição da tabela é:

/* The list of shell functions that the user has created, or that came from
   the environment. */
HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;

Funções definidas pelo usuário podem ser listadas com o declarecomando bash , outras shells ainda usam typeset. No bash declare, substituiu o typesetcomando.

declare -f

As funções existem na memória pelo tempo de vida do shell bash.

Funções definidas (incorporadas) da Shell

Estas são funções comuns, tais como echo, printf, cde :. Eles são compilados em uma biblioteca que está vinculada ao bashexecutável. Construir as definições no executável economiza tempo comparado ao carregamento de uma definição externa. As definições para essas funções (mantidas nos .defarquivos de origem que são analisados ​​em código-fonte C) são mantidas no builtinsdiretório da origem do bash.

Um útil à parte: para informações sobre o uso de um comando interno do shell help <command>. por exemplo

help                # list all builtins
help declare        # info and options for declare
help -m declare     # gives man style information for declare
suspectus
fonte
Obrigado por essa resposta do trecho. Isso é exatamente o que eu tenho procurado. Você acha que há uma ferramenta para seguir o processo de criação de funções bash ou algo assim typesetque mostraria que arquivo / script causou a criação / mudança de uma função?
Gabrijel Šimunović
Não conheço nenhuma ferramenta desse tipo - seria uma opção útil para o comando declareou typesetpara exibir o arquivo de origem de uma definição de função. Eu acho que é um problema de engenharia de software. Recentemente encontrei uma função de shell definida em um .aliasarquivo - não o que eu esperava!
suspectus
8

As funções do shell são armazenadas na memória do shell (ou, talvez, em arquivos temporários não documentados). Eles não existem em qualquer forma utilizável até o shell é iniciado (por exemplo, quando você entra em um CLI, ou iniciar uma janela de shell como xterm) e eles são definidos (por exemplo, através da leitura .bashrc, .bash_profileou algo similar) e deixam de existe quando o shell termina.

G-Man
fonte
1
A natureza efêmera de algo que você digita no prompt é importante. Meu voto vai para esta resposta. Se você digitar cd () { pwd; builtin cd "$@"; }no prompt, o único local armazenado estará na memória do seu shell em execução no momento. (Meu exemplo é Bash, mas o mesmo princípio se aplica a qualquer shell.)
tripleee
6

cde outros comandos comuns como echo, typee aliassão chamados de builtins .

Os comandos internos estão contidos dentro do próprio shell e shells diferentes podem ter diferentes comandos internos.

Nifle
fonte
4
Eu não sei se vale a pena enfatizar que o código executável para comandos embutidos cdestá contido dentro do próprio programa shell, por exemplo, dentro do arquivo, /bin/bashse este for o seu shell. (Eu acho que o seu texto aqui é claro, mas eu vi pessoas ficarem confusas com todos os tipos de coisas.)
David Z
1

A questão do super usuário Encontrar a definição de uma função bash está intimamente relacionada a esta. O usuário HairOfTheDog forneceu esta resposta (parafraseada):

Os seguintes comandos informarão a localização (nome do arquivo e número da linha) da definição de uma função. Assumindo uma função nomeada foo,

# Turn on extended shell debugging
shopt -s extdebug

# Display the function’s name, line number and fully qualified source file
declare -F foo

# Turn off extended shell debugging
shopt -u extdebug

Por exemplo, a saída desses comandos pode ser:

foo 32 /source/private/main/developer/cue.pub.sh

O acima pode funcionar apenas em bashe não em shells POSIX em geral.

Graças a framboesa azul para encontrar isso!

G-Man
fonte