GNU/Linux >> Znalost Linux >  >> Linux

Proč nemohu `tail -f /proc/$pid/fd/1`?

Zadejte strace z tail -f , to vše vysvětluje. Zajímavá část:

13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 fstatfs(3, {...}) = 0
13791 inotify_init()                    = 4
13791 inotify_add_watch(4, "/path/to/file", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1
13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 read(4, 0xd981c0, 26)             = -1 EINTR (Interrupted system call)

Co to dělá? Nastaví inotify handler k souboru a poté čeká, dokud se s tímto souborem něco nestane. Pokud jádro říká tail prostřednictvím tohoto obslužného programu inotify, že se soubor změnil (normálně byl připojen), pak tail 1) hledá 2) čte změny 3) zapisuje je na obrazovku.

/proc/3844/fd/1 ve vašem systému je symbolický odkaz na /dev/pts/14 , což je znakové zařízení. Neexistuje nic jako „paměťová mapa“, ke které by se dalo přistupovat. Neexistuje tedy nic, jehož změny by mohly být podepsány do inotify, protože neexistuje žádný disk nebo paměťová oblast, ke které by bylo možné přistupovat.

Toto znakové zařízení je virtuální terminál, který prakticky funguje, jako by to byla síťová zásuvka. Programy běžící na tomto virtuálním terminálu se připojují k tomuto zařízení (stejně jako kdybyste se připojili pomocí telnetu k tcp portu) a zapisují, do čeho chtějí zapisovat. Existují i ​​složitější věci, například zamykání obrazovky, ovládací sekvence terminálu a podobně, ty jsou běžně řešeny pomocí ioctl() hovory.

Myslím, že chcete nějak sledovat virtuální terminál. Dá se to udělat na linuxu, ale není to tak jednoduché, chce to nějakou funkcionalitu podobnou síťovému proxy a trochu složitější použití těchto ioctl() hovory. Ale existují nástroje, které to dokážou.

V současné době si nemohu vzpomenout, který balíček debian má nástroj pro tento cíl, ale s trochou googlování byste to pravděpodobně snadno našli.

Rozšíření: jak se zde zmínil @Jajesh (pokud jste mi dali, dejte mu +1), nástroj se jmenuje watch .

Rozšíření č. 2: Zmíněný @kelnos, jednoduchý cat /dev/pts/14 bylo také dost. Zkoušel jsem to a ano, fungovalo to, ale ne správně. Moc jsem s tím neexperimentoval, ale zdá se mi, jako by výstup do toho virtuálního terminálu zmizel buď na cat příkaz nebo na jeho původní umístění a nikdy na obojí. Ale není to jisté.


Soubory ve formátu /dev/pts nejsou běžné soubory, jsou to úchyty pro virtuální terminály.A pts chování pro čtení a zápis není symetrické (to znamená, že to, co je tam zapsáno, lze z něj později číst, jako běžný soubor nebo fifo/pipe), ale je zprostředkované procesem, který vytvořil virtuální terminál:některé běžné jsou xterm nebo ssh nebo agetty nebo obrazovka. Řídicí proces obvykle odešle stisknutí kláves na procesy, které čtou pts a vykreslí na obrazovce to, co píšou na pts .

Tedy tail -f /dev/pts/14 vytiskne klávesy, na které klepnete na terminálu, ze kterého jste spustili skript, a pokud to uděláte echo meh > /dev/pts/14 meh V terminálu se objeví zpráva.


Linux
  1. Proč je tisk na stdout tak pomalý? Dá se to urychlit?

  2. /proc/[pid]/pagemaps a /proc/[pid]/maps | linux

  3. Jak zjistit, ze které složky běží proces?

  1. Jak Linux zpracovává více po sobě jdoucích oddělovačů cest (/home////username///soubor)?

  2. Proč dávat věci jiné než /home do samostatného oddílu?

  3. Proč jsou < nebo > vyžadovány pro použití /dev/tcp

  1. Bash =~ Regex A Https://regex101.com/?

  2. Linux – /proc/pid/fd/x Číslo odkazu?

  3. Jak mohu zastavit proces symfony, který poslouchá na http://127.0.0.1:8000