Então, aqui temos que passar o nome do arquivo duas vezes na função
Eles não são exatamente a mesma coisa que você observa, observando que um deles é usado como argv[0]
valor. Isso não precisa ser o mesmo que o nome base do executável; muitas / a maioria das coisas o ignoram e você pode colocar o que quiser lá.
O primeiro é o caminho real para o executável, para o qual existe uma necessidade óbvia. O segundo é passado para o processo ostensivamente como o nome usado para invocá-lo, mas, por exemplo:
execl("/bin/ls", "banana", "-l", NULL);
Funcionará bem, presumindo que /bin/ls
seja o caminho correto.
Alguns aplicativos, no entanto, fazem uso argv[0]
. Normalmente, eles têm um ou mais links simbólicos $PATH
; isso é comum nos utilitários de compactação (às vezes eles usam invólucros de shell). Se você xz
instalou, stat $(which xzcat)
mostra que é um link para xz
e man xzcat
é o mesmo man xz
que explica "xzcat é equivalente a xz --decompress --stdout". A maneira como o xz pode dizer como foi invocada é verificando argv[0]
, tornando estes equivalentes:
execl("/bin/xz", "xzcat", "somefile.xz", NULL);
execl("/bin/xz", "xz", "--decompress", "--stdout", "somefile.xz", NULL);
busybox
pode ser o que você quer, dependendo de como você chama isso certo?/bin/ls
estivesse ocupado, não saberia como executarbanana
!Você não precisa passar o nome do arquivo duas vezes.
O primeiro é o arquivo que é realmente executado.
O segundo argumento é qual deve ser o
argv[0]
do processo, ou seja, qual deve ser o nome do processo. Por exemplo, se você executar als
partir do shell, o primeiro argumento é/bin/ls
, o segundo é justols
.Você pode executar um determinado arquivo e chamá-lo de outra coisa através do segundo argumento; o programa pode verificar seu nome e se comportar de maneira diferente de acordo com o nome. Isso também pode ser feito através de links físicos (ou links simbólicos), mas dessa maneira oferece mais flexibilidade.
fonte
argv[0]
como o nome do link.O argumento é que
argv[0]
pode ser definido para qualquer coisa (inclusiveNULL
). Por convenção ,argv[0]
será definido como o caminho em que o executável foi iniciado (pelo processo do shell quando o fazexecve()
).Se
./foo
e houverdir/bar
dois links diferentes (físicos ou simbólicos) para o mesmo executável, iniciar o programa a partir do shell usando os dois caminhos será definidoargv[0]
como./foo
edir/bar
, respectivamente.O fato de que
argv[0]
pode serNULL
é muitas vezes esquecido. O código a seguir pode travar porNULL
argv[0]
exemplo (embora o glibc imprima algo como <null> em vez dissoargv[0]
):Uma alternativa no Linux é usar
/proc/self/exe
para esses casos.fonte
./foo
e uma vez comodir/bar
.argv[0]
será diferente para esses dois casos (em cada caso será o mesmo que o caminho que você usou).argv[0]
qualquer coisa quando vocêexec*()
mesmo programa. É uma convenção do shell definirargv[0]
o caminho usado para iniciar o programa (e é aconselhável fazer o mesmo quando você éexec*()
um programa, pois muitos programas inspecionamargv[0]
e esperam que ele mantenha o caminho).