Kopia z propaguje Środowiska do sub-skorup, więc to działa:
$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200
ale ponieważ jest to kopia, nie można uzyskać tej wartości aż do powłoki nadrzędnej - przynajmniej przez zmianę środowiska.
Wygląda na to, że naprawdę chcesz pójść o krok dalej, czyli stworzyć coś, co będzie działać jak zmienna globalna, udostępniana przez powłoki „siostrzane” inicjowane oddzielnie od rodzica - jak twoja nowa karta w Gnome Terminal.
Najczęściej odpowiedź brzmi „nie możesz, ponieważ zmienne środowiskowe nie działają w ten sposób”. Istnieje jednak inna odpowiedź, a mianowicie, że zawsze możesz coś zhakować. Jednym podejściem byłoby zapisanie wartości zmiennej do pliku, na przykład ~/.myvar
, a następnie włączenie jej do ~/.bashrc
. Następnie każda nowa powłoka rozpocznie się od wartości odczytanej z tego pliku.
Możesz pójść o krok dalej - ustaw ~/.myvar
format MYVAR=200
, a następnie ustaw PROMPT_COMMAND=source ~/.myvar
, co spowoduje ponowne odczytanie wartości za każdym razem, gdy pojawi się nowy monit. To nie jest jeszcze dość zmienna globalna wspólna, ale to zaczyna zachowywać się jak to. Nie aktywuje się, dopóki nie pojawi się monit, co w zależności od tego, co próbujesz zrobić, może być poważnym ograniczeniem.
A potem, oczywiście, następną rzeczą jest automatyczne zapisanie zmian ~/.myvar
. To staje się trochę bardziej skomplikowane i zamierzam zatrzymać się w tym miejscu, ponieważ tak naprawdę zmienne środowiskowe nie miały być mechanizmem komunikacji między powłokami i lepiej jest po prostu znaleźć inny sposób, aby to zrobić.
To właśnie twój błąd. Powinieneś zdefiniować swoje zmienne środowiskowe
~/.profile
, które są odczytywane podczas logowania.~/.bashrc
Są odczytywane przy każdym uruchomieniu powłoki; kiedy uruchamiasz wewnętrzną powłokę, ona zastępujeMY_VAR
. Jeśli tego nie zrobiłeś, Twoja zmienna środowiskowa propagowałaby w dół.Aby uzyskać więcej informacji na temat
~/.bashrc
vs~/.profile
, zobacz moje poprzednie posty na ten temat .Zauważ, że propagacja w górę (uzyskanie zmodyfikowanej wartości z podpowłoki automatycznie odzwierciedlonej w powłoce nadrzędnej) nie jest możliwa, kropka.
źródło
Skorupa rybna może to zrobić za pomocą:
(patrz http://fishshell.com/docs/current/commands.html#set )
Aby wykonać polecenie ryby z innej powłoki, możesz uruchomić
fish -c
, np .:źródło
W ogóle nie używaj zmiennych środowiskowych. Użyj plików.
Aby zapobiec wzajemnemu narzucaniu się procesów podczas aktualizacji / odczytu pliku, użyj plików blokujących i małych skryptów aktualizujących front-end, których celem jest tylko aktualizacja pliku za 1 $, jeśli nie jest zablokowany. Pliki blokujące są implementowane poprzez sprawdzenie, czy konkretny plik istnieje (/var/run/yourscript.lck), a jeśli tak, poczekaj, aż plik zniknie na chwilę, a jeśli nie, nie powiedzie się. Musisz także usunąć plik blokujący po zakończeniu aktualizacji pliku.
Przygotuj się na sytuację, w której skrypt nie może zaktualizować pliku, ponieważ plik jest zajęty.
źródło
mkdir
działa jako atomowy test-and-create.flock(2)
ln -s dummy lockfile
(nawet jeśli jest zepsute) może również działać, ponieważ zawiedzie, jeśli dowiązanie symboliczne już istnieje. Zastanawiam się, jak to sprawdzić, czy to jest naprawdę w 100% bezpieczne.Kiedy właśnie przejrzałem to pytanie, próbowałem rozwiązać problem aktualizacji stanu (tj. Zmiennych powłoki) z podpowłoki. Aby można było przypisać zmienne, powiedzmy, wewnątrz potoku - a przypisanie byłoby transparentnie widoczne dla rodzica.
Oczywiście nie jest to możliwe w prosty sposób, ponieważ poszczególne części potoku są wykonywane w podpowłokach, które są
fork
edytowane z powłoki nadrzędnej, a zatem mają pamięć, która jest widokiem kopiowania przy zapisie w pamięci rodzica. Jednak przypuszczałem, że cienkie i przejrzyste rozwiązanie byłoby możliwe w oparciu o IPC typu „ pamięć współdzielona ” .Znalazłem nawet implementację dokładnie tego projektu ... ale jest on w Perlu.
Dodanie tej odpowiedzi i tak jako możliwego rozwiązania.
źródło