Ligeramente confundido acerca de si printf en el shell de yash es un comando incorporado o no

14

La yashcarcasa tiene una funciónprintf , de acuerdo con su manual .

Sin embargo, esto es lo que veo en un yashshell con configuración predeterminada:

kk@eeyore ~ $ command -v printf
/usr/bin/printf
kk@eeyore ~ $ type printf
printf: a regular built-in at /usr/bin/printf

¿Está printfintegrado en este shell o no? El resultado es similar para una serie de otras utilidades supuestamente integradas que también están disponibles como comandos externos.

Como comparación, en pdksh( kshen OpenBSD, donde noprintf está integrado):

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

Y en bash(donde printf está incorporado):

$ command -v printf
printf
$ type printf
printf is a shell builtin
Kusalananda
fuente
1
Es un incorporado, un incorporado normal , no especial . Si usted está confundido acerca de la diferencia entre especiales y regulares muebles empotrados o conducta dispuesto por la norma (véase la búsqueda y ejecución de comandos 1.eia) - que requiere que un binario debe existir en PATHel fin de regular de una función de para ser ejecutado, entonces haga su pregunta al respecto.
mosvy
1
@mosvy Este era un detalle del estándar que desconocía para mí. Si quieres convertir eso en una respuesta, estaría feliz. No creo que deba actualizar la pregunta para que sea una respuesta adecuada, ya que no tenía conocimiento de este detalle en particular. O lo escribiré yo mismo más tarde.
Kusalananda

Respuestas:

14

La yashcáscara hace tener, y hace uso, una versión incorporada de printf(y otros servicios públicos). Simplemente resulta que es muy pedagógicamente compatible con POSIX en la forma en que formula el resultado de la command -vytype comandos .

Como comenta mosvy , el estándar POSIX requiere que un habitual comando integrado estará disponible como un comando externo en $PATHla versión integrada del comando a ejecutar.

Este es el texto relevante del estándar :

Búsqueda de comandos y ejecución

Si un comando simple da como resultado un nombre de comando y una lista opcional de argumentos, se realizarán las siguientes acciones:

  1. Si el nombre del comando no contiene ningún carácter <slash>, se producirá el primer paso exitoso en la siguiente secuencia:

    • a. Si el nombre del comando coincide con el nombre de una utilidad incorporada especial, se invocará esa utilidad incorporada especial.

      [...]

    • mi. De lo contrario, se buscará el comando utilizando la variable de entorno PATH como se describe en Variables de entorno XBD:
      • yo. Si la búsqueda es exitosa:
        • a. Si el sistema ha implementado la utilidad como una función incorporada regular o como una función de shell, se invocará en este punto en la búsqueda de ruta.
        • si. De lo contrario, el shell ejecuta la utilidad en un entorno de utilidad [...] separado
          .
      • ii. Si la búsqueda no tiene éxito, el comando fallará con un estado de salida de 127 y el shell escribirá un mensaje de error.
  2. Si el nombre del comando contiene al menos una <barra inclinada>, [...]

Esto significa que la salida de command -v printfsignifica que el printfcomando se encontró en la ruta de búsqueda, mientras que la salida detype printf agrega a esto que el comando es un elemento incorporado normal.

Dado que el printfcomando se encontró en la ruta de búsqueda, y dado que es una función integrada normal en el shell, yashllamará a su versión integrada del comando . Si la printfse no encuentra en el camino, y si la yashcáscara estaba corriendo en POSIX-ly modo correcto, se habría generado un error en lugar.

yashse enorgullece de ser un shell muy compatible con POSIX, y esto también es cierto si miramos lo que POSIX dice sobrecommand -v :

-v

Escriba una cadena en la salida estándar que indique el nombre de ruta o el comando que utilizará el shell, en el entorno de ejecución de shell actual (consulte Shell Execution Environment ), para invocar command_name, pero no invocar command_name.

  • Las utilidades, las utilidades integradas habituales , command_namesincluido un <slash>carácter, y cualquier función definida por la implementación que se encuentre utilizando la PATHvariable (como se describe en Búsqueda y ejecución de comandos ), se escribirán como nombres de ruta absolutos .
Kusalananda
fuente
3
¿Alguien sabe por qué POSIX tiene este requisito para que exista un comando externo antes de ejecutar el comando incorporado?
studog
@studog Es posible que desee hacer eso como una nueva pregunta por separado, posiblemente refiriéndose a esta respuesta o pregunta
Kusalananda
6

La carcasa de Watanabe tiene tres tipos de elementos integrados, que se describen en detalle en su manual. Todos los comandos integrados también se enumeran allí, pero uno tiene que inferir que algo es un comando incorporado "normal" por la ausencia de una nota que diga que el comando es un "especial" o un "semi-especial" incorporado. Las incorporaciones regulares no están marcadas.

printfes uno de esos "regulares" integrados. En modo nativo, siempre se invoca, independientemente de si se encuentra un comando externo con ese nombre.

$ PATH = / usr / bin 
$ printf
printf: este comando requiere un operando
$ tipo printf
printf: un incorporado regular en / usr / bin / printf
PS
$ RUTA = / 
$ printf
printf: este comando requiere un operando
$ tipo printf
printf: un incorporado normal (no se encuentra en $ PATH)
PS

Pero cuando la posixly-correctopción de shell está configurada, solo está integrada si el comando externo se puede encontrar en el PATH.

$ set --posixly-correct
PS
$ PATH = / usr / bin 
$ printf
printf: este comando requiere un operando
PS
$ RUTA = / 
$ printf
yash: no existe ese comando `printf '
PS

Esto es realmente conforme a lo que dice la Especificación Single Unix, y lo ha dicho al menos desde 1997.

Difiere del shell Z, el shell 93 Korn, el shell Bourne Again y el shell Debian Almquist, ninguno de los cuales implementa o documenta tal comportamiento para las incorporaciones regulares. El shell Z, por ejemplo, documenta que siempre se encuentran elementos integrados regulares , antes del paso que busca PATH. También lo hace el shell Debian Almquist. Y eso es lo que hacen todos estos shells, incluso si se invocan como shcon sus opciones de encendido POSIX.

% / bin / exec -a sh zsh -c "RUTA = /; tipo printf; printf"
printf es un shell incorporado
zsh: printf: 1: no hay suficientes argumentos
% / bin / exec -a sh ksh93 -c "RUTA = /; tipo printf; printf"
printf es un shell incorporado
Uso: formato printf [opciones] [cadena ...]
% / bin / exec -a sh bash --posix -c "RUTA = / tipo printf; printf"
printf es un shell incorporado
printf: uso: printf [-v var] formato [argumentos]
% / bin / exec -a sh dash -c "RUTA = /; tipo printf; printf"
printf es un shell incorporado
sh: 1: printf: uso: formato printf [arg ...]
% 

Sin embargo, no se ejecuta printfcuando no está PATHactivado el comportamiento del shell PD Korn, el shell Heirloom Bourne y el shell MirBSD Korn; porque no tienen un printfincorporado en primer lugar. ☺

% / bin / exec -a sh `comando -v ksh` -c" RUTA = /; escriba printf; printf "
printf no encontrado
sh: printf: no encontrado
% / bin / exec -a sh `comando -v oksh` -c" RUTA = /; escriba printf; printf "
printf no encontrado
sh: printf: no encontrado
% / bin / exec -a sh `comando -v jsh` -c" RUTA = /; escriba printf; printf "
printf no encontrado
sh: printf: no encontrado
% / bin / exec -a sh mksh -c "RUTA = /; tipo printf; printf"
printf no encontrado
sh: printf: no encontrado
% ksh -c "tipo printf; printf"
printf es un alias rastreado para / usr / bin / printf
uso: formato printf [argumentos ...]
% oksh -c "tipo printf; printf"
printf es un alias rastreado para / usr / bin / printf
uso: formato printf [argumentos ...]
% jsh -c "tipo printf; printf"
printf es hash (/ usr / bin / printf)
uso: formato printf [argumentos ...]
% mksh -c "tipo printf; printf"
printf es un alias rastreado para / usr / bin / printf
uso: formato printf [argumentos ...]
PS
JdeBP
fuente
¡Bueno! ¡Gracias por confirmar y por agregar los bits específicos de shell a mi conocimiento! Me gusta más este caparazón.
Kusalananda
-1

La redacción podría mejorarse.

Si el shell está en modo posix set --posixly-correct::

Para las incorporaciones regulares que no existen en la RUTA, esto se imprime:

pushd: a regular built-in (not found in $PATH)

Lo cual es una descripción clara: es un archivo incorporado pero no hay un ejecutable con el mismo nombre en la RUTA.

Sin embargo, para las incorporaciones regulares cuyo nombre también existe en la RUTA, esto se imprime:

echo: a regular built-in at /bin/echo

Lo cual parece implicar que se ejecutará el ejecutable en / bin / echo (que no se ejecutará). Sugiero que un cambio de ata also found in PATH at:

echo: a regular built-in also found in PATH at /bin/echo

haría una mejor descripción. Quizás incluir eso entre paréntesis (como lo hizo la otra respuesta) podría mejorarlo.


En el modo POSIX, no funcionará ninguna construcción regular a menos que también se encuentre en la RUTA.

Sin embargo, ambos (POSIX) especiales:

break colon continue dot eval exec exit export
readonly return set shift times trap unset

Y semi-especial de yash (no especial para POSIX):

alias bg cd command false fc fg getopts jobs
kill pwd read true umask unalias wait

Los builtins todavía funcionan.

Isaac
fuente