ta odpowiedź może przyjść trochę za późno, ale miałem ten sam problem, a zaakceptowana odpowiedź nie wydawała mi się całkiem satysfakcjonująca, więc poszukałem nieco dalej.
Co mi nie przeszkadzało to fakt, że $0
albo $PROGRAM_NAME
tak naprawdę nie posiadają prawidłowe informacje o tym, co użytkownik miał wpisane . Jeśli mój skrypt Ruby znajdował się w folderze PATH, a użytkownik wprowadził nazwę pliku wykonywalnego (bez żadnych definicji ścieżek, takich jak ./script
lub /bin/script
), zawsze rozwijałby się on do ścieżki całkowitej.
Myślałem, że to niedobór Rubiego, więc spróbowałem tego samego z Pythonem i ku mojemu rozczarowaniu nie było inaczej.
Znajomy zasugerował mi, żebym poszukał real thing
in /proc/self/cmdline
, a wynik był następujący: [ruby, /home/danyel/bin/myscript, arg1, arg2...]
(oddzielone znakiem null-char). Ten złoczyńca jest tym, execve(1)
który rozszerza ścieżkę do całkowitej ścieżki, kiedy przekazuje ją tłumaczowi.
Przykładowy program w C:
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);
}
Wynik: Użycie: / home / danyel / bin / myscript PLIK ...
Aby udowodnić, że to rzeczywiście jest execve
rzecz, a nie z basha, możemy stworzyć fałszywego interpretera, który nic nie robi, tylko wypisuje przekazane mu argumenty:
// interpreter.c
int main(int argc, const char ** argv) {
while(*argv)
printf("%s\n", *(argv++));
}
Kompilujemy go i umieszczamy w folderze ze ścieżką (lub umieszczamy pełną ścieżkę po shebang) i tworzymy fałszywy skrypt w ~/bin/myscript/
Hi there!
Teraz w naszym main.c:
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);
}
Kompilowanie i uruchamianie ./main
: interpreter / home / danyel / bin / myscript -v /var/log/apache2.log
Przyczyną tego jest najprawdopodobniej to, że jeśli skrypt znajduje się w Twojej PATH, a pełna ścieżka nie została podana, interpreter rozpozna to jako No such file
błąd, co zrobi, jeśli to zrobisz: ruby myrubyscript --options arg1
i nie ma Cię w folderze z tym skryptem .