programas - scripts bash ejemplos
¿Cómo cambiar argv0 en bash para que el comando aparezca con un nombre diferente en ps? (7)
En un programa en C puedo escribir argv [0] y el nuevo nombre aparece en una lista de ps.
¿Cómo puedo hacer esto en bash?
Copia el ejecutable de bash a un nombre diferente.
Puedes hacer esto en el propio script ...
cp /bin/bash ./new-name
PATH=$PATH:.
exec new-name $0
Si está intentando fingir que no es una secuencia de comandos de shell, puede cambiar el nombre de la secuencia de comandos a "cool" o incluso a "" (un solo espacio) para que
exec new-name " "
Ejecutará bash su secuencia de comandos y aparecerá en la lista de ps como new-name
.
OK, llamar a un script "" es una muy mala idea :)
Básicamente, para cambiar el nombre.
bash script
cambiar el nombre de bash y cambiar el nombre del script.
Si está preocupado, como Sr. McDoom. aparentemente es, sobre la copia de un binario a un nuevo nombre (que es completamente seguro) también podría crear un enlace simbólico
ln -s /bin/bash ./MyFunkyName
./MyFunkyName
De esta manera, el enlace simbólico es lo que aparece en la lista ps. (nuevamente use PATH = $ PATH :. si no quiere el ./)
He tenido la oportunidad de revisar la fuente de bash y no parece que haya soporte para escribir en argv [0].
Puede hacerlo cuando ejecute un nuevo programa a través de exec -a <newname>
.
Solo añadiré que esto debe ser posible en tiempo de ejecución, al menos en algunos entornos. Asignar $ 0 en perl en linux cambia lo que aparece en ps. Sin embargo, no sé cómo se implementa. Si puedo averiguarlo, actualizaré esto.
Edición: basado en cómo lo hace perl, no es trivial. Dudo que haya algún tipo de gusto en el tiempo de ejecución, pero no estoy seguro. Puede ver cómo perl establece el nombre del proceso en tiempo de ejecución .
Solo para el registro, aunque no responde exactamente a la pregunta del póster original, esto es algo trivial que ver con zsh
:
ARGV0=emacs nethack
Supongo que tiene un script de shell que desea ejecutar, de modo que el proceso del script tiene un nuevo argv[0]
. Por ejemplo (solo he probado esto en bash, así que lo estoy usando, pero esto puede funcionar en otro lugar).
#!/bin/bash
echo "process $$ here, first arg was $1"
ps -p $$
La salida será algo como esto:
$ ./script arg1
process 70637 here, first arg was arg1
PID TTY TIME CMD
70637 ttys003 0:00.00 /bin/bash ./script arg1
Así que ps
muestra el shell, /bin/bash
en este caso. Ahora pruebe el exec -a
su shell interactivo, pero en una subshell para que no destruya el shell interactivo:
$ (exec -a MyScript ./script arg1)
process 70936 here, first arg was arg1
PID TTY TIME CMD
70936 ttys008 0:00.00 /bin/bash /path/to/script arg1
Woops, sigue mostrando /bin/bash
. ¿que pasó? El exec -a
probablemente configuró argv[0]
, pero luego comenzó una nueva instancia de bash porque el sistema operativo decía #!/bin/bash
en la parte superior de su script. Ok, ¿qué pasa si realizamos la ejecución dentro del script de alguna manera? Primero, necesitamos alguna forma de detectar si esta es la "primera" ejecución del script, o la segunda instancia ejecutada, de lo contrario, la segunda instancia ejecutará nuevamente, y así sucesivamente en un bucle infinito. Luego, necesitamos que el ejecutable no sea un archivo con una línea #!/bin/bash
en la parte superior, para evitar que el sistema operativo cambie nuestro argv deseado [0]. Aquí está mi intento:
$ cat ./script
#!/bin/bash
__second_instance="__second_instance_$$"
[[ -z ${!__second_instance} ]] && {
declare -x "__second_instance_$$=true"
exec -a MyScript "$SHELL" "$0" "$@"
}
echo "process $$ here, first arg was $1"
ps -p $$
Gracias a esta respuesta , primero __second_instance_$$
variable de entorno __second_instance_$$
, basada en el PID (que no cambia a través de exec
) para que no coincida con otros scripts usando esta técnica. Si está vacío, asumo que esta es la primera instancia, y exporto esa variable de entorno, luego exec. Pero, lo que es más importante, no ejecuto este script, sino que ejecuto el shell binary directamente, con este script ( $0
) como argumento, pasando también todos los demás argumentos ( $@
). La variable de entorno es un poco de un hack.
Ahora la salida es esta:
$ ./script arg1
process 71143 here, first arg was arg1
PID TTY TIME CMD
71143 ttys008 0:00.01 MyScript ./script arg1
Eso es casi allí. El argv[0]
es MyScript
como quiero, pero hay ese arg ./script
adicional que es una consecuencia de la ejecución del shell directamente (en lugar de a través del procesamiento #!
sistema operativo). Desafortunadamente, no sé cómo ser mejor que esto.
( exec -a foo bash -c ''echo $0'' )