GNU/Linux >> Znalost Linux >  >> Linux

Způsob, jak specifikovat, aby byl úsek potrubí zcela „průchozí“?

Mám skript, ve kterém se data zpracovávají tak, že je streamují poměrně velkým potrubím. Několik částí potrubí jsou ve skutečnosti funkcemi „rozvaděče“, které dělají různé věci na základě nějakého externího parametru. Vymyšlený příklad je uveden níže.

#! /bin/bash

switchboard() {
    # Select the appropriate command depending on input.
    case "$1" in
        1)
            sort
            ;;
        2)
            awk '{ print $5 }' | sort
            ;;
        *)
            cat  # <= Is there something more optimal here?
            ;;
    esac
}

# The data processing pipeline.
<"$1" tr '[:upper:]' '[:lower:]' | switchboard "$2" | head -n 10

Ve funkci „ústředna“ je záložním řešením pouze použití cat k odeslání vstupu přímo na výstup. Funguje to dobře, ale ve svém potrubí mám možná mnoho „rozvaděčů“ a rád bych se vyhnul vytváření hromady nicnedělání cat procesy, pokud je to možné.

Existuje nějaký vestavěný bash (nebo alternativa), který lze použít k určení, že daná část potrubí by měla připojit STDOUT přímo k STDIN, aniž by bylo nutné použít podproces? (Zkoušel jsem : ale to jen sežralo data) Nebo cat používat tak malé množství zdrojů, že to není problém?

Přijatá odpověď:

Za prvé, použití další cat ve skutečnosti to moc nemění a neměli byste si s tím lámat hlavu.

Za druhé, příkazy, které tvoří kanál, se stejně provádějí v samostatných procesech, bez ohledu na to, zda se jedná o externí příkazy nebo vestavěné:

$ a=0
$ a=1 | a=2 | a=3
$ echo $a
0

Pokud jde o váš přesný problém, není možné jednoduše připojit „stdin“ k „stdout“; i když shell měl nějaké nop vestavěný, který by se při použití v potrubí zhroutil (např. | nop | -> | ), shell nemá žádný způsob, jak vědět předem, v době, kdy nastavuje potrubí, že se vaše „ústředna“ přepne na nop místo awk nebo sort .

Můžete také dosáhnout stejného efektu, jako kdybyste „rozvaděči“ postavili potrubí sami a poté zavolali eval, aby ho spustil. Příklad:

$ cat test.shtype=`file -zi "$1"`case $type in*application/gzip*) mycat='zcat "$1"';;*) mycat='cat "$1"';;esaccase $type in*charset=utf-16le*) mycat="$mycat | iconv -f utf16le";;esac# zvýraznit komentáře v blueesc=`printf '
Linux
  1. Záhlaví souborů ELF

  2. Jakýkoli způsob, jak určit umístění dat profilu

  3. Přidání sekce do souboru ELF

  1. Existuje způsob, jak restartovat špatné bloky?

  2. Panel Mate úplně pryč

  3. V Crontab obecný způsob, jak zadat každých n minut, kde n > 60

  1. 10 článků, ve kterých se naučíte Linux po svém

  2. CFS:Naprosto spravedlivé plánování procesů v Linuxu

  3. Úplně resetovat PostgreSQL na výchozí?