Você geralmente vê isso no caso de utilitários como busybox
, um programa que pode fornecer a maioria dos utilitários unix comuns em um executável, que se comporta diferente dependendo de sua invocação / busybox
pode executar várias funções, acpid
a zcat
.
E geralmente decide o que deve fazer olhando o parâmetro argv[0]
para main()
. E isso não deveria ser uma comparação simples. Porque argv[0]
pode ser algo como sleep
ou pode ser /bin/sleep
e deve decidir fazer a mesma coisa. Em outras palavras, o caminho vai tornar as coisas mais complexas.
Portanto, se as coisas forem feitas corretamente pelo programa worker, seu wrapper de logging poderá ser executado a partir de algo como /bin/realstuff/make_tea
e se o worker examinar argv[0]
basename only, a função correta deverá ser executada.
#!/bin/sh -
myexec=/tmp/MYEXEC$$
mybase='basename -- "$0"'
echo "$0 $@" >> logfile
mkdir "$myexec" || exit
ln -fs /usr/bin/real/do_stuff "$myexec/$mybase" || exit
"$myexec/$mybase" "$@"
ret=$?
rm -rf "$myexec"
exit "$ret"
No exemplo acima, argv[0]
deve ler algo como /tmp/MYEXEC4321/make_tea
(se 4321 fosse o PID para o /bin/sh
que foi executado), o que deve acionar o basename make_tea
behavior
Se você quiser que argv[0]
seja uma cópia exata do que seria sem o wrapper, você terá um problema mais difícil. Por causa dos caminhos de arquivos absolutos que começam com /
. Você não pode criar um novo /bin/sleep
(ausente chroot
e eu não acho que você queira ir lá). Como você observou, você poderia fazer isso com algum sabor de exec()
, mas não seria um invólucro de shell.
Já pensou em usar um alias para acertar o registrador e iniciar o programa de base em vez de um wrapper de script? Ele só pegaria um conjunto limitado de eventos, mas talvez esses sejam os únicos eventos com os quais você se importa