Mam program, w którym są przechowywane jego ustawienia ~/.config/myprogram
którego używam zarówno interaktywnie, jak i z systemem kolejkowania wsadowego. Podczas działania interaktywnego chcę, aby ten program używał moich plików konfiguracyjnych (i robi to). Ale podczas pracy w trybie wsadowym pliki konfiguracyjne nie są konieczne, ponieważ określam opcje wiersza polecenia, które zastępują wszystkie odpowiednie ustawienia. Ponadto dostęp do plików konfiguracyjnych przez sieć wydłuża czas uruchamiania programu o kilka sekund; jeśli pliki nie istnieją, program uruchamia się znacznie szybciej (ponieważ każde zadanie zajmuje tylko około minuty, ma to znaczący wpływ na przepustowość zadań wsadowych). Ponieważ jednak korzystam z programu interaktywnie, nie chcę cały czas przenosić / usuwać plików konfiguracyjnych. W zależności od tego, kiedy moje zadania wsadowe zostaną zaplanowane w klastrze (na podstawie wykorzystania przez innych użytkowników),
(Poza tym: wydajność pliku sieciowego jest tak niska, prawdopodobnie jest to błąd, ale jestem tylko użytkownikiem klastra, więc mogę tylko go obejść, a nie naprawić).
Mógłbym zbudować wersję programu, która nie odczytuje plików konfiguracyjnych (lub ma opcję wiersza poleceń, aby tego nie robić) do użycia wsadowego, ale środowisko kompilacji tego programu jest źle zaprojektowane i trudne do skonfigurowania. Wolałbym używać plików binarnych zainstalowanych za pomocą menedżera pakietów mojego systemu.
Jak mogę oszukać poszczególne instancje tego programu, aby udawać, że moje pliki konfiguracyjne nie istnieją (bez modyfikacji programu)? Mam nadzieję na opakowanie formularza pretendfiledoesntexist ~/.config/myprogram -- myprogram --various-options...
, ale jestem otwarty na inne rozwiązania.
LD_PRELOAD
haka. To łatwiejsze (możesz to zaimplementować za godzinę lub dwie, jeśli znasz C) niż alternatywa, którą jestptrace
. Prawdopodobnie możesz też użyć do tego fakechroot (jak sądzę, LD_PRELOAD).Odpowiedzi:
Ten program prawdopodobnie rozpoznaje ścieżkę do tego pliku z
$HOME/.config/myprogram
. Możesz więc powiedzieć, że twój katalog domowy znajduje się gdzie indziej, na przykład:Być może twój program potrzebuje innych zasobów w twoim katalogu domowym. Jeśli wiesz, które to są, możesz przygotować fałszywy dom dla swojego programu z linkami do potrzebnych tam zasobów.
źródło
Jeśli wszystko inne zawiedzie, napisz bibliotekę opakowań, którą będziesz wstrzykiwać
LD_PRELOAD
, abyopen("/home/you/my-program/config.interactive")
przechwycić wywołanie, ale inne przejdzie. Działa to dla każdego rodzaju programu, nawet skryptów powłoki, ponieważ będzie filtrować wywołania systemowe.Uwaga: Nie testowałem tego kodu i nie jestem w 100% pewien, że ta
errno
część działa.Zobacz, jak
fakeroot
to działa w przypadku połączeń takich jakgetuid(2)
istat(2)
.Zasadniczo linker połączy tę aplikację z biblioteką, która zastępuje
open
symbol. Ponieważ nie możesz używać dwóch różnych funkcji nazwanychopen
we własnej bibliotece, musisz je rozdzielić na drugą część (np.get_real_open
), Która z kolei będzie prowadzić do pierwotnegoopen
wywołania.Oryginalny:
./Application
Przechwycone:
LD_PRELOAD=yourlib_wrap.so ./Application
Edycja: Najwyraźniej istnieje
ld
flaga, którą można włączyć (--wrap <symbol>
), która pozwala pisać opakowania bez konieczności podwójnego łączenia:źródło
Odsuń plik konfiguracyjny i napisz opakowanie powłoki dla interaktywnego przypadku użycia, który kopiuje plik do normalnego miejsca docelowego, uruchamia program i usuwa go przy wyjściu.
źródło
Powinno to być możliwe w przypadku unionfs / aufs. Tworzysz
chroot
środowisko dla procesu. Używasz prawdziwego katalogu jako warstwy tylko do odczytu i umieszczasz na nim pusty. Następnie podłącz wolumin unionfs do odpowiedniego katalogu wchroot
środowisku i tam usuń plik. Proces tego nie zobaczy, ale wszyscy inni to zrobią.źródło
Zmień nazwę pliku konfiguracyjnego na np
config.interactive
. Utwórz kolejny pusty plik o nazwie npconfig.script
.Teraz utwórz miękkie łącze o nazwie
config
(lub cokolwiek aplikacja oczekuje jako plik konfiguracyjny) do dowolnej potrzebnej konfiguracji i uruchom aplikację.Pamiętaj, aby później uporządkować swój link.
źródło
Jeśli dokładnie scharakteryzowałeś sposób, w jaki twój program korzysta z pliku konfiguracyjnego, przeoczyłem go. Wiele programów (takich jak
bash
ivi
) sprawdza plik konfiguracyjny natychmiast po uruchomieniu; jeśli plik istnieje, przeczytaj go i zamknij. Te programy nigdy więcej nie uzyskują dostępu do tych plików inicjujących. Jeśli twój program jest taki, czytaj dalej.Wiem, że odrzuciłeś odpowiedzi, które sprawiają, że plik konfiguracyjny naprawdę nie istnieje (zmieniając jego nazwę), ale mam zmarszczkę, której nikt inny nie widział. Zrób to, gdy wywołasz program w trybie wsadowym:
To usuwa plik konfiguracyjny z drogi, ale następnie przesuwa go o sekundę wstecz, nawet jeśli
myprogram
nadal działa. Tworzy to bardzo krótkie okno czasu, w którym plik jest niedostępny - jakie jest prawdopodobieństwo, że program będzie uruchamiany interaktywnie podczas tego okna? (Nawet jeśli to zrobisz, możesz po prostu wyjść i uruchomić ponownie, a plik konfiguracyjny prawdopodobnie wróci na swoje miejsce).To tworzy warunki wyścigu; jeśli program zajmuje zbyt dużo czasu, aby przejść do otwarcia pliku, może uzyskać prawdziwy plik. Jeśli zdarza się to wystarczająco często, że jest to problem, po prostu zwiększ wartość DELAY_TIME.
źródło
I jak Stephane odpowiedź, ale to będzie oszukać dowolny program do przypuszczeń, każdy plik jest pusty - (ponieważ jego dentry tymczasowo wskazuje na plik, który rzeczywiście jest pusta) :
Możesz także:
Jeśli chciałeś.
źródło
mv
pliku - która może mieć inne konsekwencje niż wpływ na jego uzębienie, takie jak obcięcie pliku lub innych itd. - podczas gdy operacja działa tylko na. Mimo to należyunshare
, żemount
chyba ...