El estándar de shell POSIX dice en este sitio
http://pubs.opengroup.org/onlinepubs/9699919799/
sobre cómo usan los shells PATH
para buscar ejecutables:
"Se buscará en la lista de principio a fin, aplicando el nombre de archivo a cada prefijo, hasta que se encuentre un archivo ejecutable con el nombre especificado y los permisos de ejecución apropiados".
Bueno, no es así como parece funcionar en la implementación POSIX real:
man which
dice:
"devuelve los nombres de ruta de los archivos (o enlaces) que se ejecutarían en el entorno actual, si sus argumentos se hubieran dado como comandos en un shell estrictamente compatible con POSIX. Lo hace buscando en la RUTA archivos ejecutables que coincidan con los nombres de argumentos. No sigue enlaces simbólicos ".
OK, veamos esta situación:
$ pwd
/home/mark
$ echo $PATH
/home/mark/bin:
...
$ ls -l bin/foobar
lrwxrwxrwx 1 mark mark 18 Dec 12 22:51 bin/foobar -> /home/mark/foobar1
$ touch foobar1
$ which foobar
$ chmod a+x foobar1
$ which foobar
/home/mark/bin/foobar
OK, aquí hay un enlace simbólico PATH
con el nombre correcto, y se informa ls
que es ejecutable.
which
no lo mira en absoluto, pero solo le interesa lo que señala.
Eso a pesar del hecho de que ambos man which
dicen explícitamente que no sigue enlaces simbólicos (y de hecho vemos que no lo hace, porque which foobar
no se imprime foobar1
), y también que la documentación del shell POSIX citada anteriormente, nunca menciona los siguientes enlaces simbólicos en el PATH
algoritmo.
Entonces, ¿están which
mal los shells existentes o no entiendo la documentación?
PARA ACLARAR:
Sé y puedo explicar el comportamiento existente. Mi pregunta no es "¿cómo funciona esto?". Eso lo sé.
Mi pregunta es sobre la documentación: ¿dónde está mi error al seguir la documentación que cité? ¿O está mal la documentación?
MOTIVACIÓN: ¿Por qué me importa?
Bueno, soy un implementador. Los diferentes implementadores tienen diferentes requisitos. Para mí, el requisito es que la palabra del estándar POSIX actual DEBE seguirse EXACTAMENTE (o, más precisamente, lo mejor que puede ser, porque el estándar en sí es algo defectuoso). Como si fuera la palabra de Dios.
Ahora, la redacción estándar es bastante clara: no se mencionan los enlaces simbólicos, donde en muchos otros lugares, se menciona dónde debe hacerse. Entonces, en este caso, no lo hagas.
Sin embargo, siempre verifico cómo dash
y cómo me bash
comporto, solo para asegurarme. Ahora, por supuesto, también hay un pequeño problema aquí, dash
aunque se factura como POSIX, tiene muchos pequeños errores conformes con POSIX. bash
, Todavía no he encontrado ningún error con POSIX, pero ... bash no es realmente POSIX, es mucho más que eso.
Entonces ahí lo tienes. Por eso me importa.
$PATH
no tiene enlaces simbólicos.
lstat(2)
), por lo general, no se indica su seguimiento. Por ejemplo, la descripción de open(2)
solo menciona enlaces simbólicos cuando se habla del comportamiento de O_CREAT | O_EXCL
. No es necesario indicar que se abrirá el archivo de destino.
$PATH
lata contiene enlaces simbólicos. Tratarwhich sh
.