Um pouco confuso sobre se printf no shell yash é um comando interno ou não

Um pouco confuso sobre se printf no shell yash é um comando interno ou não

O yashshell tem um printfbuilt-in,de acordo com seu manual.

No entanto, é isso que vejo em um yashshell com configuração padrão:

$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf

Está printfembutido neste shell ou não? O resultado é semelhante para vários outros utilitários supostamente integrados que também estão disponíveis como comandos externos.

Como comparação, em pdksh( kshno OpenBSD, onde printfestánãoum integrado):

$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf

E em bash(ondeprintf éum integrado):

$ command -v printf
printf
$ type printf
printf is a shell builtin

Responder1

A yashconchafaztem e usa uma versão integrada de printf(e outros utilitários). Acontece que ele é muito pedantemente compatível com POSIX na forma como formula o resultado dos comandos command -ve .type

Como muitos comentários, o padrão POSIX exige que um comando interno regular esteja disponível como um comando externo $PATHpara que a versão interna do comando seja executada.

Isso éo texto relevante da norma:

Pesquisa e execução de comandos

Se um comando simples resultar em um nome de comando e uma lista opcional de argumentos, as seguintes ações deverão ser executadas:

  1. Se o nome do comando não contiver nenhum caractere <barra>, ocorrerá a primeira etapa bem-sucedida na seguinte sequência:

    • a. Se o nome do comando corresponder ao nome de um utilitário integrado especial, esse utilitário integrado especial deverá ser invocado.

      [...]

    • e. Caso contrário, o comando deve ser pesquisado usando a variável de ambiente PATH conforme descrito em Variáveis ​​de Ambiente XBD:
      • eu.Se a pesquisa for bem-sucedida:
        • a.Se o sistema implementou o utilitário como uma função interna regular ou como uma função shell, ele deverá ser invocado neste ponto da pesquisa de caminho.
        • b. Caso contrário, o shell executa o utilitário em um ambiente de utilitário separado [...
          ]
      • ii. Se a pesquisa não for bem-sucedida, o comando falhará com um status de saída 127 e o shell escreverá uma mensagem de erro.
  2. Se o nome do comando contiver pelo menos uma <barra>, [...]

Isso significa que a saída de command -v printfsignifica que o printfcomandoeraencontrado no caminho de pesquisa, enquanto a saída de type printfacrescenta que o comando é um built-in regular.

Como o printfcomando foi encontrado no caminho de pesquisa e como é um arquivo integrado regular no shell,yashchamará sua versão interna do comando. Se o printffossenãoencontrado no caminho, e se o yashshell estivesse sendo executado no modo POSIX correto, um erro teria sido gerado.

yashse orgulha de ser um shell muito compatível com POSIX, e isso também é verdade se olharmos parao que o POSIX diz sobrecommand -v:

-v

Escreva uma string na saída padrão que indique o caminho ou comando que será usado pelo shell, no ambiente de execução atual do shell (vejaAmbiente de execução Shell), para invocar command_name, mas não invocar command_name.

  • Serviços de utilidade pública,utilitários integrados regulares, command_namesincluindo um <slash>caractere e quaisquer funções definidas pela implementação encontradas usando a PATHvariável (conforme descrito emPesquisa e execução de comandos),devem ser escritos como nomes de caminhos absolutos.

Responder2

O shell Watanabe possui três tipos de recursos integrados, descritos detalhadamente em seu manual. Todos os comandos internos também estão listados lá, mas é preciso inferir que algo é um comando interno "normal" doausênciade qualquer nota dizendo que o comando é um "especial" ou um "semi-especial" embutido. Os integrados regulares não estão marcados.

printfé um desses integrados "regulares". No modo nativo ésempreinvocado, independentemente de haver um comando externo encontrado com esse nome.

$PATH=/usr/bin
$imprimir
printf: este comando requer um operando
$digite printf
printf: um built-in regular em /usr/bin/printf
$
$CAMINHO=/
$imprimir
printf: este comando requer um operando
$digite printf
printf: um built-in regular (não encontrado em $PATH)
$

Mas quando a posixly-correctopção shell está definida, ela só será incorporada se o comando externo puder ser encontrado no arquivo PATH.

$definir --posixly-correto
$
$PATH=/usr/bin
$imprimir
printf: este comando requer um operando
$
$CAMINHO=/
$imprimir
yash: esse comando não existe `printf'
$

Na verdade, isso está em conformidade com o que diz a Especificação Única Unix, e tem dito desde pelo menos 1997.

Ele difere do shell Z, do shell 93 Korn, do shell Bourne Again e do shell Debian Almquist, nenhum dos quais implementa ou documenta tal comportamento para integrados regulares. O shell Z, por exemplo, documenta que os integrados regulares sãosempreencontrado,antesa etapa que pesquisa PATH. O mesmo acontece com o shell do Debian Almquist. E é isso que todos esses shells fazem, mesmo se invocados como acontece shcom suas opções de ativação POSIX.

%/bin/exec -a sh zsh -c "PATH=/; digite printf; printf"
printf é um shell embutido
zsh:printf:1: argumentos insuficientes
%/bin/exec -a sh ksh93 -c "PATH=/; digite printf; printf"
printf é um shell embutido
Uso: printf [opções] formato [string ...]
%/bin/exec -a sh bash --posix -c "PATH=/ digite printf; printf"
printf é um shell embutido
printf: uso: printf [-v var] formato [argumentos]
%/bin/exec -a sh dash -c "PATH=/ ; digite printf ; printf"
printf é um shell embutido
sh: 1: printf: uso: formato printf [arg ...]
%

No entanto, não executar printfquando não está ligado PATHé o comportamento do shell PD Korn, do shell Heirloom Bourne e do shell MirBSD Korn; porque eles não têm um printfembutido em primeiro lugar. ☺

%/bin/exec -a sh `comando -v ksh` -c "PATH=/ ; digite printf ; printf"
printf não encontrado
sh: printf: não encontrado
%/bin/exec -a sh `command -v oksh` -c "PATH=/ ; digite printf ; printf"
printf não encontrado
sh: printf: não encontrado
%/bin/exec -a sh `comando -v jsh` -c "PATH=/ ; digite printf ; printf"
printf não encontrado
sh: printf: não encontrado
%/bin/exec -a sh mksh -c "PATH=/; digite printf; printf"
printf não encontrado
sh: printf: não encontrado
%ksh -c "digite printf; printf"
printf é um alias rastreado para /usr/bin/printf
uso: formato printf [argumentos...]
%oksh -c "digite printf; printf"
printf é um alias rastreado para /usr/bin/printf
uso: formato printf [argumentos...]
%jsh -c "digite printf; printf"
printf é hash (/usr/bin/printf)
uso: formato printf [argumentos...]
%mksh -c "digite printf; printf"
printf é um alias rastreado para /usr/bin/printf
uso: formato printf [argumentos...]
$

informação relacionada