Si escribo
::
en un bash shell, obtengo:
-bash: ::: command not found
Pero, solo uno no :
produce resultados. ¿Por qué es esto?
Si escribo
::
en un bash shell, obtengo:
-bash: ::: command not found
Pero, solo uno no :
produce resultados. ¿Por qué es esto?
Respuestas:
:
shell incorporado frente a inexistente::
El :
comando incorporado de shell existe (observe la diferencia entre los comandos externos e integrados ) que no hace nada; simplemente devuelve el éxito, al igual que el true
comando. El :
incorporado es estándar y está definido por el estándar POSIX , donde también se conoce como la "utilidad nula". Se usa con frecuencia para probar o para ejecutar bucles infinitos como enwhile : ; do ...;done
bash-4.3$ type :
: is a shell builtin
Sin embargo, ::
dos caracteres de dos puntos juntos se interpretan como una "palabra" para el shell, y se supone que es un comando que ingresó el usuario. El shell pasará por el proceso de verificación de las funciones integradas, luego cualquier directorio en la PATH
variable para la existencia de ese comando. Pero no hay un ::
comando incorporado ni externo ::
. Por lo tanto, eso produce un error.
Bueno, ¿cuál es un formato típico para un error?
<shell>: <command user typed>: error message
Por lo tanto, lo que ves no son 3 puntos sino lo que escribiste pegado en el formato de error estándar.
Tenga en cuenta también que :
puede tomar argumentos de línea de comandos, es decir, es legal hacerlo:
: :
En este caso, el shell considerará eso como dos "palabras", una de las cuales es un comando y la otra un parámetro posicional. ¡Eso tampoco producirá ningún error! (Consulte también la nota histórica (más adelante en esta respuesta) sobre el uso de los :
parámetros posicionales).
Tenga en cuenta que el formato también puede variar entre diferentes shells. Para bash
, ksh
y mksh
el comportamiento es consistente. Por ejemplo, el /bin/sh
shell predeterminado de Ubuntu (que en realidad es /bin/dash
):
$ dash
$ ::
dash: 1: ::: not found
donde 1 es el número de comando (equivalente al número de línea en un script).
csh
por el contrario no produce ningún mensaje de error:
$ csh
% ::
%
De hecho, si ejecuta strace -o csh.trace csh -c ::
, la salida de rastreo en el csh.trace
archivo revela que csh
sale con el estado de salida 0 (sin errores). Pero tcsh
genera el error (sin generar su nombre):
$ tcsh
localhost:~> ::
::: Command not found.
En general, el primer elemento en el mensaje de error debe ser el proceso o la función de ejecución (su shell intenta ejecutarse ::
, por lo tanto, el mensaje de error proviene del shell). Por ejemplo, aquí el proceso de ejecución es stat
:
$ stat noexist
stat: cannot stat 'noexist': No such file or directory
De hecho, POSIX define la función perror () , que de acuerdo con la documentación toma un argumento de cadena, luego emite un mensaje de error después de dos puntos y luego una nueva línea. Citar:
La función perror () asignará el número de error al que se accede a través del símbolo errno a un mensaje de error dependiente del idioma, que se escribirá en el flujo de error estándar de la siguiente manera:
Primero (si s no es un puntero nulo y el carácter al que apunta s no es el byte nulo), la cadena a la que apunta s seguido de dos puntos y un <space>.
Luego aparece una cadena de mensaje de error seguida de una <línea nueva>.
Y el argumento de cadena para perror()
técnicamente podría ser cualquier cosa, pero, por supuesto, para mayor claridad, generalmente es el nombre de la función o argv[0]
.
Por el contrario, GNU tiene su propio conjunto de funciones y variables para el manejo de errores , que un programador puede usar fprintf()
para stderr
transmitir. Como muestra uno de los ejemplos en la página vinculada, se podría hacer algo como esto:
fprintf (stderr, "%s: Couldn't open file %s; %s\n",
program_invocation_short_name, name, strerror (errno));
En el antiguo shell de Unix y Thompson, :
se usaba con una goto
declaración (que según el usuario llamado Perderabo en este hilo no era un shell incorporado). Cita del manual:
Se busca en el archivo de comando completo una línea que comience con: como el primer carácter no en blanco, seguido de uno o más espacios en blanco y luego la etiqueta. Si se encuentra dicha línea, goto reposiciona el desplazamiento del archivo de comando a la línea después de la etiqueta y sale. Esto hace que el shell se transfiera a la línea etiquetada.
Entonces, podría hacer algo como esto para hacer un script de bucle infinito:
: repeat
echo "Hello World"
goto repeat
command.com
y Windows cmd.exe
tienen una situación similar pero opuesta: :
es explícitamente una etiqueta de goto (no un comando) y a menudo se reutiliza como un carácter de comentario (por ejemplo :: This is a comment
).
Los dos puntos finales son solo parte del mensaje predeterminado "no encontrado":
$ x
x: command not found
$ ::
::: command not found
La razón por la que un solo colon no produce nada es que :
es un comando válido, aunque no hace nada (excepto el retorno TRUE
). De la SHELL BUILTIN COMMANDS
sección de man bash
:
: [arguments]
No effect; the command does nothing beyond expanding arguments
and performing any specified redirections. A zero exit code is
returned.
A veces lo verás en construcciones como
while :
do
something
done
Ver por ejemplo ¿ Para qué sirve el colon incorporado?
Los dos puntos añadidos son parte del mensaje de error en sí. Si uno teclea cd ow
, da como resultado bash: cd: ow: No such file or directory
, lo que muestra que el error está poniendo el colon extra: No such file or directory
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found
el tercero es un espaciador del formateo
en bash a :
es una instrucción vacía de línea vacía