Załóżmy, że mam skrypt script.sh
, którego wykonanie zajmuje trochę czasu. I wykonać ją ./script.sh
. Gdy jest uruchomiony w oknie terminala, modyfikuję plik script.sh
. Czy będzie to miało jakiś wpływ na już uruchomiony proces?
Po zmodyfikowaniu go wykonuję zmodyfikowany plik, więc mam teraz dwa uruchomione procesy. Czy to w porządku?
scripts
filesystem
becko
źródło
źródło
Odpowiedzi:
Wprowadzając zmiany w skrypcie, dokonujesz zmian na dysku (dysk twardy - pamięć stała); po uruchomieniu skryptu skrypt jest ładowany do pamięci (RAM).
Tak więc zmiany, które wprowadzisz w skrypcie, nie wpłyną na uruchomiony skrypt, uruchomi on wersję wykonaną przed wprowadzeniem tych zmian.
Jednak po ponownym uruchomieniu zmienionego skryptu bez kończenia poprzednio działającej instancji pojawią się dwie instancje skryptu - jedna ze zmianami i stara.
Ostrzegamy, że zasoby używane i modyfikowane przez skrypt będą powodować konflikty. Na przykład, jeśli modyfikujesz plik za pomocą skryptu, skrypt, który zostanie uruchomiony później, nie będzie mógł otworzyć tego pliku do zapisu i nie wykona się poprawnie.
Aktualizacja: Dziękujemy Zarejestrowanemu Użytkownikowi za wskazanie lepszej odpowiedzi na Unix.stackexchange.com.
W zależności od wielkości skryptu i danego kompilatora / interpretera skrypt jest ładowany częściowo / całkowicie. Jeśli więc skrypt nie zostanie całkowicie załadowany, zmiany wprowadzone w skrypcie zostaną odzwierciedlone w działającej instancji po załadowaniu części skryptu do pamięci.
Dlatego nie jest zalecane zmienianie skryptu na dysku, który jest obecnie uruchomiony w celu uzyskania nieprzewidzianych danych wyjściowych: Najpierw zatrzymaj działającą instancję, a następnie zmodyfikuj skrypt, a następnie ponownie uruchom skrypt.
źródło
Dodam coś, co moim zdaniem nie zostało powiedziane w innych odpowiedziach. Wiele zależy od sposobu edycji pliku. Wydaje mi się, że działanie
echo "stuff" >file
z powłoki (inna instancja) rzeczywiście nadpisze plik. Ale jeśli na przykład edytujesz plik,emacs
a następnie zapiszesz, tak się nie stanie. Zamiast tego edytor zmienia nazwę starego pliku na nazwę kopii zapasowej (być może faktycznie usuwa poprzednią kopię zapasową), a następnie zapisuje zmodyfikowaną zawartość bufora jako nowy plik o (teraz za darmo) starej nazwie . Ponieważ powłoka (lub inny interpreter) czytająca skrypt prawie na pewno otworzy plik tylko raz, jest on następnie niezależny od miejsca, w którym znajduje się nazwa pliku, po prostu kontynuuje odczytywanie pliku dysku fizycznego (identyfikowanego przez numer i-węzła), który był powiązany z nazwą pliku w momencie otwierania. Więc nawet jeśli czyta skrypt w blokach (co byłoby najłatwiejszym rozwiązaniem, jeśli używasz buforowanego tekstu we / wy), nadal czytałby wiersze ze starej instancji pliku, co prawdopodobnie nie zmieni się podczas edycji.źródło
emacs
?należy to zaktualizować, powyższe odpowiedzi są teraz tylko częściowo poprawne:
w przypadku bieżącej wersji bash modyfikacja skryptu na dysku podczas działania spowoduje, że bash „spróbuje” załadować zmiany do pamięci i przyjąć je w działającym skrypcie. jeśli zmiany nastąpią po aktualnie wykonywanej linii, nowe linie zostaną załadowane i wykonane. ale jest to zgadywanie przez bash i może to zrobić dobrze lub źle.
lepszym sposobem na to jest następująca sekwencja czynności: 1) załaduj skrypt do pamięci 2) usuń skrypt z dysku 3) napisz nowy skrypt na dysku, usuwając najpierw wersję dysku, wersja pamięci traci do niej linki tak, że gdy podasz nową wersję w kroku 3, nie zostanie podjęta próba bash załadowania nowej zawartości do wersji pamięci.
źródło
Odpowiedź @ jobin jest ogólnie poprawna, ale dodam kilka innych odpowiedzi, które mogą być do rzeczy, w zależności od tego, co chcesz zrobić.
Jeśli chcesz zmienić skrypt i chcesz wiedzieć, że jest bezpieczny, to chcesz napisać do nowego pliku, a nie do istniejącego. Nowy plik może być zlokalizowany tam, gdzie był stary. Napisz nową wersję do nowego pliku, a następnie użyj,
mv
aby przenieść ją na miejsce nad starą wersją . Zastąpiony plik nadal istnieje, po prostu nie jest powiązany z katalogiem. Uruchomiony skrypt może dalej go używać, a kiedy ten skrypt zamyka uchwyt pliku, system wie, że może bezpiecznie wyczyścić plik (natychmiast lub później).Jeśli chcesz zachować zachowanie skryptu w locie, masz trudniejszy problem. Oczekuję, że będziesz musiał wbudować go w kod skryptu. Skrypty Bash mogą obsługiwać sygnały (np. Mogą przechwycić coś podobnego
kill -USR1 [pid]
), a skrypt może następnie odpowiedzieć poprzez ponowne załadowanie kodu. Może więc możesz uzyskać funkcjonalność zbliżoną do tego, czego chcesz, ale nie wiedząc, czego szukasz, nie widzę dobrego powodu, aby to zrobić, i podejrzewam, że jeśli chcesz zrobić coś tak złożonego, prawdopodobnie chcesz bardziej wyrafinowanego język programowania, aby to zrobić.Jeśli chcesz zhakować zachowanie działającego skryptu, który nie został napisany z myślą o tym, nie masz szczęścia. Wahałbym się przed nazwaniem jakiegokolwiek zadania programistycznego niemożliwym, ale gdybyś miał zasoby i umiejętności do tego rodzaju zadania, prawdopodobnie nie zapytałbyś tutaj.
źródło