GNU/Linux >> Znalost Linux >  >> Linux

Jak zajistit, aby jakýkoli program fungoval s příkazem Tee?

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.
Související:Jak se program rozhodne, zda bude či nebude mít barevný výstup?

Další čtení

  • https://unix.stackexchange.com/a/249801/5132

Linux
  1. Jak auditovat oprávnění pomocí příkazu find

  2. Jak zajistit, aby Iconv nahradil vstupní soubor převedeným výstupem?

  3. Zavření standardního výstupu (>&-)?

  1. Jak zachytit terminálové relace a výstup pomocí příkazu skriptu Linux

  2. Jak přiřadit výstup příkazu proměnné shellu?

  3. Jak funguje příkaz ps?

  1. Ve skriptu Bash Jak funguje příkaz Continue s vestavěnými smyčkami?

  2. Jak funguje příkaz Exit na Unixovém terminálu?

  3. Jak funguje Tee Command?