A partir dessa pergunta sobre se printf é um built-in para yash , vem esta resposta que cita o padrão POSIX .
A resposta indica que a sequência de pesquisa POSIX é encontrar uma implementação externa do comando desejado e, se o shell o implementou como interno, execute o interno. (Para embutidos que não são embutidos especiais .)
Por que o POSIX tem esse requisito para que uma implementação externa exista antes de permitir que uma implementação interna seja executada?
Parece ... arbitrário, então estou curioso.
shell
posix
shell-builtin
studog
fonte
fonte
printf
disponíveis.PATH
e depois chamaria o utilitário interno , não o script externo. E se você quiser chamar o script externo no seu caminho? Hmm ... Isso parece exigir uma tabela descrevendo as diferentes possibilidades. Há um aqui , mas não faz sentido para mim.Respostas:
Esta é uma regra "como se".
Simplificando: o comportamento do shell, como os usuários o vêem, não deve mudar se uma implementação decidir disponibilizar um comando externo padrão também como embutido no shell.
O contraste que mostrei em /unix//a/496291/5132 entre os comportamentos (por um lado) dos projéteis PD Korn, MirBSD Korn e Heirloom Bourne; (por outro lado) as conchas Z, 93 Korn, Bourne Again e Debian Almquist; e (na mão emocionante) a concha Watanabe destaca isso.
Para os shells que não têm
printf
como interno, a remoção/usr/bin
dePATH
faz uma invocação deprintf
parar de funcionar. O comportamento de conformidade POSIX, exibido pelo shell Watanabe em seu modo de conformidade, causa o mesmo resultado. O comportamento do shell que possui umprintf
built-in é como se estivesse invocando um comando externo.Enquanto o comportamento de todos os shells não-conformes não se altera se
/usr/bin
for removidoPATH
e eles não se comportam como se estivessem invocando um comando externo.O que o padrão está tentando garantir a você é que os shells podem incorporar todos os tipos de comandos normalmente externos (ou implementá-los como suas próprias funções de shell), e você ainda terá o mesmo comportamento dos incorporados que fez. com os comandos externos se você ajustar
PATH
para impedir que os comandos sejam encontrados.PATH
continua sendo sua ferramenta para selecionar e controlar quais comandos você pode chamar.(Como explicado em /unix//a/448799/5132 , anos atrás, as pessoas escolheram a personalidade de seu Unix alterando o que estava acontecendo
PATH
.)Pode-se opinar que fazer o comando sempre funcionar, independentemente de poder ser encontrado,
PATH
é de fato o objetivo de criar comandos normalmente externos internos. (É por isso que meu conjunto de ferramentas nosh ganhou umprintenv
comando interno na versão 1.38, de fato. Embora este não seja um shell.)Mas o padrão está lhe dando a garantia de que você verá o mesmo comportamento para comandos externos regulares que não estão no
PATH
shell, como verá em outros programas não-shell que invocam aexecvpe()
função, e o shell não será capaz de magicamente execute (aparentemente) comandos externos comuns que outros programas não podem encontrar com o mesmoPATH
. Tudo funciona de forma autônoma da perspectiva do usuário ePATH
é a ferramenta para controlar como funciona.Leitura adicional
fonte
Isso é um absurdo e é por isso que nenhum shell está implementando-o no modo padrão.
Do padrão de raciocínio e sua ilustrando exemplo sugerem que esta foi uma tentativa fracassada de ter um regulares built-in associada a um caminho, e deixar o usuário substituí-lo por ter o seu próprio binário comparecer perante ele em
PATH
(ex. Umprintf
built-in associado com/usr/bin/printf
pode ser substituído pelo/foo/bin/printf
comando externo, definindoPATH=/foo/bin:$PATH
).No entanto, o padrão não acabou exigindo isso, mas algo completamente diferente (e também inútil e inesperado).
Você pode ler mais sobre isso neste relatório de bug . Citação do texto final aceito :
FWIW, acho que também não há nenhum shell implementando os requisitos revisados do texto aceito.
fonte
/usr/bin/printf
ou/foo/bin/printf
no PATH ativará o printf interno . A única coisa que um externo ausente (no PATH)printf
fará é desativar o builtin. (Pela letra da especificação).