cette réponse pourrait venir un peu en retard, mais j'ai eu le même problème et l'on a accepté la réponse ne semble pas tout à fait satisfaisant pour moi, donc j'ai étudié un peu plus loin.
Ce qui me dérange est le fait que l' $0
ou $PROGRAM_NAME
n'ont pas vraiment la bonne information sur ce que l'utilisateur a tapé. Si mon script Ruby était dans un dossier du CHEMIN d'accès et l'utilisateur a entré le nom de l'exécutable (sans chemin définitions ./script
ou /bin/script
), il serait toujours élargir le chemin d'accès total.
Je pensais que c'était un Rubis deficite, j'ai donc essayé la même chose avec Python et à mon grand regret là, il n'était pas différent.
Un ami m'a suggéré un hack pour chercher l' real thing
en /proc/self/cmdline
, et le résultat était: [ruby, /home/danyel/bin/myscript, arg1, arg2...]
(séparés par le null-char). Le méchant ici, est - execve(1)
qui s'étend de la chemin de la chemin totale quand il passe à un interprète.
Exemple de programme C:
#include <stdlib.h>
#include <unistd.h>
extern char** environ;
int main() {
char ** arr = malloc(10 * sizeof(char*));
arr[0] = "myscript";
arr[1] = "-h";
arr[2] = NULL;
execve("/home/danyel/bin/myscript", arr, environ);
}
Sortie: `Usage: /home/danyel/bin/script FICHIER...
Pour prouver que c'est effectivement un execve
chose et pas de bash, nous pouvons créer un mannequin interprète qui ne fait rien mais imprimer les arguments passés à elle:
// interpreter.c
int main(int argc, const char ** argv) {
while(*argv)
printf("%s\n", *(argv++));
}
Nous le compiler et de le placer dans un dossier du chemin d'accès (ou de mettre le chemin complet après le shebang) et de créer un mannequin script en ~/bin/myscript/
#!/usr/bin/env interpreter
Hi there!
Maintenant, dans notre main.c:
#include <stdlib.h>
extern char** environ;
int main() {
char ** arr = malloc(10 * sizeof(char*));
arr[0] = "This will be totally ignored by execve.";
arr[1] = "-v";
arr[2] = "/var/log/apache2.log";
arr[3] = NULL;
execve("/home/danyel/bin/myscript", arr, environ);
}
La compilation et l'exécution ./main
:
interprète
/home/danyel/bin/script
-v
/var/log/apache2.journal
La raison la plus probable est que si le script est dans votre CHEMIN d'accès et le chemin d'accès complet étaient pas fournis, l'interprète de reconnaître cela comme un No such file
d'erreur, ce qu'il fait si vous n': ruby myrubyscript --options arg1
et vous n'êtes pas dans le dossier contenant le script.