Napsal jsem program (v Ruby) a fungoval dobře. Vytiskne několik řádků textu a poté se na minutu zastaví a poté zopakuje výše uvedené.
Funguje to dobře (v terminálu Mac OS X), ale poznamenal jsem, že pokud chci uchovat záznam o výstupu, pomocí
ruby myscript.rb | tee record.txt
pak se výstup nezobrazí na obrazovce, dokud výstup nedosáhne určitého množství, možná pár kb. To však může znamenat 5 nebo 10 minut bez ničeho na obrazovce (a také nic v souboru, pokud stisknu CTRL-C).
Mohl bych upravit program tak, aby výstup vyprázdnil, ale myslel jsem, že aplikace by měla být agnostická, pokud jde o to, co se používá s výstupem do STDOUT. Stejně tak tee
fungovat dobře (možná s možností) nebo lze použít jakýkoli jiný příkaz, nebo je to možná možnost Bash nebo aplikace Terminal? Existuje způsob?
Přijatá odpověď:
Myslel jsem, že aplikace by měla být agnostická, pokud jde o to, co se používá s výstupem do STDOUT.
Myslel sis špatně. Runtime knihovny několika programovacích jazyků, včetně jazyků C a C++, všechny sdílejí sémantiku změny ukládání do vyrovnávací paměti podle toho, zda detekují, že je stream připojen k terminálovému zařízení.
To je v mnoha případech definovaná část jazyka. Standard jazyka C říká například:
Při prvním otevření není standardní chybový proud plně ukládán do vyrovnávací paměti; standardní vstupní a standardní výstupní toky jsou plně ukládány do vyrovnávací paměti tehdy a pouze tehdy, pokud lze určit, že tok neodkazuje na interaktivní zařízení.
Obvyklá volba, pokud tok není připojen k terminálovému zařízení, je vybrat ukládání do vyrovnávací paměti jednotky, ukládání do vyrovnávací paměti řádku nebo úplné ukládání do vyrovnávací paměti. Unit buffering a line buffering jsou obvyklé pro standardní chybu; plné vyrovnávací paměti pro standardní výstup. To se však liší podle jazyka.
Chcete-li tedy dosáhnout toho, aby výstup nebyl plně ukládán do vyrovnávací paměti, když je výstupní proud roura v takových jazycích, musíte
- zapište svůj program do sebe, aby standardní výstupní řádek byl vyrovnávací paměť, inteligentní vyrovnávací paměť nebo bez vyrovnávací paměti;
- použijte věci, které zachycují běhovou knihovnu vašeho konkrétního programovacího jazyka, jako je
stdbuf
příkaz if váš programovací jazyk je C nebo jako základ používá (jeho část I/O proudy) běhovou knihovnu C (což některé programovací jazyky nemají); nebo - použijte nástroje jako
ptybandage
které nutí program si myslet, že jeho standardním výstupem je terminál, přičemž tento výstup vezme a odešle jej do zapisovacího konce roury.
Další čtení
- https://unix.stackexchange.com/a/249801/5132