<rant>
“running a function definition” and “running the definition of a function” are not common idioms. I expect that most people would refer to that simply as “defining a function”. OK, that phrase might be interpreted to refer to
- conceptually specifying the characteristics and interfaces (parameters and other inputs, processing, and outputs) of a function (this is an activity performed by a person, or a group of people)
- choosing the implementation of a function; i.e., what commands to use in the function body. This is an activity performed by a person, or a group of people, possibly using paper, whiteboards, and/or blackboards.
- typing the implementation of a function into a text editor or directly into an interactive shell (this, of course, is also an activity performed by a person, or possibly a group of people, or possibly a very intelligent and dexterous cat, dog or monkey)
If you fear confusion with the above, you might be better served by phrases like “reading a function definition” and “processing the definition of a function”.
You say, “A function definition is a command.” It’s not clear what a claim like that even means — it’s a matter of semantics — but, at the semantic level, it’s debatable. Section 3.2 of the Bash manual (Shell Commands) lists six kinds of shell commands: Simple Commands, Pipelines, Lists, Compound Commands, Coprocesses, and GNU Parallel. Function definitions don’t fit well into any of those categories.
</rant>
Chegando à sua pergunta e observando as sete etapas / operações,
- A leitura de entrada obviamente tem que acontecer antes que qualquer coisa mais possa acontecer. É, novamente, uma questão de semântica você poderia dizer que a entrada de leitura de um arquivo ou outra fonte de texto de fluxo faz parte de "ler uma definição de função" ou que é um pré-requisito / prelúdio para “Processando a definição de uma função”.
- Quebrando a entrada em palavras e operadores
é claramente parte do “processamento da definição de uma função”.
- Quebrar a entrada em tokens é, claro, um pré-requisito / prelúdio para analisar os tokens (passo 3, abaixo).
- O manual diz "A expansão do alias é executada por esta etapa" e você mostra na pergunta que você sabe que expansão de alias ocorre quando a definição da função é lida.
-
Analisando os tokens. Isso deve pelo menos começar durante a fase “processamento da definição de uma função” para o shell perceber que ele está olhando para uma definição de função e não um simples comando. Além disso, podemos fazer este experimento simples: digite um dos seguintes itens em um shell:
myfunc1() { myfunc2() { < or ; } }
Ele falhará com um "erro de sintaxe" antes de você ter a chance de digitar o
}
. (>
e&
produzem o mesmo efeito.) Então, claramente, este passo faz parte do processamento da definição da função.
- Realizando as várias expansões de shell
faz parte de chamar a função.
- Você mostra na pergunta que você sabe que expansão de parâmetro não acontece quando a definição da função é lida.
- É igualmente trivial demonstrar que a expansão do nome do caminho / nome do arquivo
não acontece quando a definição da função é lida.
No seu exemplo, altere
echo $var
(que deve serecho "$var"
, mas isso é outro assunto) paraecho *
.- Se você olhar para a definição da função,
você verá que ainda diz
echo *
e não foi expandido. - Alterar diretório (
cd
) e / ou criar arquivo (s) e / ou excluir arquivo (s) e / ou renomear arquivo (s), e então chame (execute) a função. Você verá que ela exibe a lista atual de arquivos 1 no diretório atual, e não reflete o conteúdo do diretório onde / quando você definiu a função.
- Se você olhar para a definição da função,
você verá que ainda diz
- A execução de redirecionamentos faz parte da chamada da função.
Isso também é trivial para verificar.
No seu exemplo, altere
echo $var
paraecho hello > myfile
.- Se você olhar para a definição da função,
você verá que ainda diz
> myfile
. - Verifique o diretório,
e você verá que
myfile
não foi criado (ainda).
- Se você olhar para a definição da função,
você verá que ainda diz
- Executando o comando - você realmente precisa perguntar?
- Aguardar a conclusão do comando não pode acontecer até que o comando tenha sido executado (passo 6), então isso, obviamente, é realizado apenas quando chamamos a função.
Em outras palavras, exatamente o que @ilkkachu disse .
O único caso especial excepcional em que posso pensar
é que os passos 2 e 3 (análise lexical e análise) ocorrem (de novo)
ao executar uma função se a função contiver eval
declarações
- mas acredito que isso esteja fora do escopo
do que sua pergunta está realmente perguntando.