Ostrożnie z edycją skryptów bash
Napisał: Patryk Krawaczyński
09/05/2020 w Hacks & Scripts Brak komentarzy. (artykuł nr 735, ilość słów: 459)
P
isząc i uruchamiając skrypty bash lepiej poczekać z ich edycją do czasu aż zakończą swoje działanie. Dlaczego? W naszym ulubionym edytorze stwórzmy prosty skrypt:
#!/bin/bash sleep 30 #echo "All your base are belong to us!" echo "Done!"
Jeśli uruchomimy go teraz w jednym oknie terminala to po 30 sekundach powinniśmy otrzymać tylko i wyłącznie komunikat o treści: Done!. Dobrze, a teraz po uruchomieniu go w pierwszym oknie terminala – z poziomu innego okna edytujmy jego zawartość, gdy ten jeszcze nie przekroczył czasu 30 sekund i usuńmy zero (0) z trzydziestki zostawiając samą trójkę (3), czyli finalnie nasz skrypt powinien mieć postać:
#!/bin/bash sleep 3 #echo "All your base are belong to us!" echo "Done!"
Co wypisał teraz skrypt w pierwszym oknie? Jak to możliwe skoro przy pierwszym komunikacje echo
jest znak komentarza, który wyklucza wykonanie tego polecenia? Dzieje się tak, ponieważ bash podczas wykonywania skryptu odczytuje jego zawartość w kawałkach, a śledzi swoje aktualne położenie za pomocą przesunięć bajtów:
root@darkstar:~# strace bash ./delay.sh # Otwórz skrypt openat(AT_FDCWD, "delay.sh", O_RDONLY) = 3 # Przeanalizuj pierwszą linię (aż do 80 znaków) read(3, "#!/bin/bash\nsleep 30\n#echo \"All "..., 80) = 79 # Wróć do początku lseek(3, 0, SEEK_SET) = 0 # Przesuń to na deskryptor pliku 255 dup2(3, 255) = 255 # Przeczytaj fragment 79 bajtów, aby uzyskać polecenie read(255, "#!/bin/bash\nsleep 30\n#echo \"All "..., 79) = 79 # Ustaw kursor z powrotem na końcu polecenia, które mamy wykonać # Przesunięcie na 21 to znak "#" lseek(255, -58, SEEK_CUR) = 21 # Wykonaj instrukcję sleep wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 13741 # Zanim wait4 się zakończyło nastąpiła edycja "30" na "3" # i tym samym znak "#" na pozycji 21 zamienił się na "e"cho # Przeczytaj fragment 79 bajtów, aby uzyskać kolejne polecenie read(255, "echo \"All your base are belong t"..., 79) = 57 # bash postanowił wykonać oba echa jednocześnie # tworząć niuans podczas wykonania skryptu write(1, "All your base are belong to us!\n", 32All your base are belong to us!) = 32 write(1, "Done\n", 5Done) = 5 # Przeczytaj kolejny fragment i odkryj, że jesteśmy na końcu pliku (EOF) read(255, "", 73) = 0
Więc zachowajmy ostrożność podczas edycji już uruchomionego skryptu bash, ponieważ możemy doprowadzić do wykonania nieprawidłowego polecenia lub zrobić coś bardzo zaskakującego.
Więcej informacji: Take care editing bash scripts