Entonces aquí tenemos que pasar el nombre del archivo dos veces en la función.
No son exactamente lo mismo que observa al observar que uno de ellos se usa como argv[0]
valor. Esto no tiene que ser el mismo que el nombre base del ejecutable; muchas / la mayoría de las cosas lo ignoran y puedes poner lo que quieras allí.
El primero es la ruta real al ejecutable, para lo cual existe una necesidad obvia. El segundo se pasa al proceso aparentemente como el nombre utilizado para invocarlo, pero, por ejemplo:
execl("/bin/ls", "banana", "-l", NULL);
Funcionará bien, suponiendo que /bin/ls
es el camino correcto.
Algunas aplicaciones, sin embargo, hacen uso de argv[0]
. Por lo general, estos tienen uno o más enlaces simbólicos en $PATH
; Esto es común con las utilidades de compresión (a veces usan envoltorios de shell). Si lo ha xz
instalado, stat $(which xzcat)
muestra que es un enlace xz
y man xzcat
es el mismo man xz
que explica "xzcat es equivalente a xz --decompress --stdout". La forma en que xz puede determinar cómo se invocó es comprobando argv[0]
, haciendo estos equivalentes:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
busybox
puede ser lo que quieres que sea, dependiendo de cómo lo llames, ¿verdad?/bin/ls
fuera busybox, ¡no sabría cómo ejecutarbanana
!No tiene que pasar el nombre del archivo dos veces.
El primero es el archivo que realmente está ejecutado.
El segundo argumento es lo que debería ser el
argv[0]
proceso, es decir, lo que el proceso debería ver como su nombre. Por ejemplo, si se ejecutals
desde el shell, el primer argumento es/bin/ls
, el segundo es justols
.Puede ejecutar un determinado archivo y llamarlo de otra manera a través del segundo argumento; el programa puede verificar su nombre y comportarse de manera diferente según el nombre. Esto también se puede hacer a través de enlaces duros (o enlaces simbólicos) pero de esta manera se da más flexibilidad.
fuente
argv[0]
en el nombre del enlace.La conclusión es que
argv[0]
se puede establecer en cualquier cosa (incluidoNULL
). Por convención ,argv[0]
se establecerá en la ruta en la que se inició el ejecutable (por el proceso de shell cuando lo haceexecve()
).Si
./foo
ydir/bar
son dos enlaces diferentes (duros o simbólicos) al mismo ejecutable, entonces el inicio del programa desde el shell utilizando las dos rutas se estableceráargv[0]
en./foo
ydir/bar
, respectivamente.El hecho de que
argv[0]
puede ser aNULL
menudo se pasa por alto. El siguiente código podría bloquearse para unNULL
argv[0]
por ejemplo (aunque glibc imprime algo como <null> en su lugarargv[0]
):Una alternativa en Linux es usar
/proc/self/exe
para tales casos.fuente
./foo
y una vez comodir/bar
.argv[0]
será diferente para esos dos casos (en cada caso será la misma que la ruta que utilizó).argv[0]
cualquier cosa cuando ustedexec*()
mismo programa. Es una convención del shell establecerargv[0]
la ruta que se usó para iniciar el programa (y es aconsejable hacer lo mismo cuandoexec*()
un programa, ya que muchos programas inspeccionanargv[0]
y esperan que mantenga la ruta).