Od kilku dni uruchamiam skrypt. Przekierowałem stdout na $HOME/mylog
, ale nie przekierowałem stderr, ponieważ myślałem, że nic na tym nie będzie. Nagle na stderr zaczęły wychodzić tysiące linii, więc zawiesiłem pracę. Czy istnieje sposób, w jaki mogę teraz przekierowywać stderr $HOME/myerr
bez konieczności restartowania skryptu?
Mam dostęp do sudo na pudełku i jest to OS X.
Być może coś przy użyciu pułapki dtools?
Nie mogę stracić pracy wykonanej dotychczas przez skrypt i zrestartować go od zera. Czy istnieje sposób na „zrzucenie obiektów w pamięci” na dysk, zamrożenie programu, edycję zmiennych (np. Deskryptorów plików) i wznowienie pracy z nowym kontekstem?
bash
io-redirection
stdout
Robottinosino
źródło
źródło
Odpowiedzi:
Myślę, że jest to możliwe, jeśli dołączysz proces powiązanego interpretera do gdb. Próbowałem tego z tym linkiem perl
i działa, ale niestety nie z podobnym skryptem bash.
Przede wszystkim musisz ustalić PID tego procesu, którego wyjście chcesz uchwycić. Następnie uruchom
gdb
w innym terminalu i wykonaj następujące polecenia gdbpotem całe dane, które są zapisywane
stderr
jest przekierowany/abs/olu/te/path/filename
, ponieważattach PID
dołącza proces do gdb i zatrzymuje gocall close(2)
zamykastderr
skryptowy skrypt procesu (dlastdout
skryptowego pliku jest 1)call open(...)
otwiera nowy plik i przyjmuje najniższą nieużywaną liczbę całkowitą dla nowo utworzonego skryptu plików idetach PID
kontynuuje procesPrzynajmniej na mojej maszynie. Pierwsze dwie linie są kompatybilne z POSIX, ale nie trzecia.
Drugi i trzeci argument
open
w trzeciej linii są udokumentowane wman 2 open
. W moim przypadku 65 oznacza, żeopen
należy utworzyć plik i otworzyć plik tylko do zapisu, tj.O_WRONLY | O_CREAT
(Zdefiniowany wfcntl.h
). Trzeci argument mówi open, aby utworzyć plik z uprawnieniami do odczytu i zapisu dla użytkownika, tj.S_IWUSR | S_IRUSR
(Zdefiniowany wsys/stat.h
). Może więc musisz samodzielnie znaleźć odpowiednie wartości na swoim komputerze.źródło
To prymitywna odpowiedź i mam nadzieję, że ktoś inny poradzi sobie lepiej, ale jeśli nie pojawią się żadne inne pomysły, dołącz gdb i zmuś proces do wykonania kilku wywołań systemowych:
źródło
open()
chwyta FD 1? A może po prostu dzwoniszdup()
kilka razy?p open("errfile", O_WRONLY)
naprawdę działają na komputerze?p dup2(xxx, 2)
a następniep close(xxx)
gdziexxx
jest zwracana wartośćopen
. To trudna sprawa, lepiej nie używać tych poleceń w długotrwałym procesie, dopóki nie będziesz pewien, że nie ma innego wyjścia./dev/null
jako mojego,errfile
więc nie potrzebowałemO_CREAT
. AO_WRONLY
bycie makrem, czy się rozwija, czy nie, zależy od tego, czy gdb zatrzymał proces w linii, w której dostępne są symbole debugowania i makro jest zdefiniowane. Wstrzykiwanie kodu do procesu za pomocą gdb jest niebezpieczne i nikt nie powinien kopiować tych poleceń bez ich zrozumienia.