GNU/Linux >> Tutoriales Linux >  >> Linux

Canalizar la salida a la función bash

No puede canalizar cosas directamente a una función bash como esa, sin embargo, puede usar read para tirar de él en su lugar:

jc_hms() {
  while read -r data; do
      printf "%s" "$data"
  done
}

debería ser lo que quieres


Para responder a su pregunta real, cuando una función de shell está en el extremo receptor de una tubería, all hereda la entrada estándar comandos en la función, pero solo los comandos que realmente leen desde su entrada estándar consumen datos. Para los comandos que se ejecutan uno tras otro, los comandos posteriores solo pueden ver lo que no consumen los comandos anteriores. Cuando dos comandos se ejecutan en paralelo, qué comandos ven qué datos depende de cómo el sistema operativo programa los comandos.

Desde printf es el primer y único comando en su función, la entrada estándar se ignora efectivamente. Hay varias formas de evitarlo, incluido el uso de read incorporado para leer la entrada estándar en una variable que se puede pasar a printf :

jc_hms () {
    read foo
    hr=$(($foo / 3600))
    min=$(($foo / 60))
    sec=$(($foo % 60))
    printf "%d:%02d:%02d" "$hr" "$min" "$sec"
}

Sin embargo, dado que su necesidad de una canalización parece depender de su necesidad percibida de usar awk , permítanme sugerir la siguiente alternativa:

printstring=$( jc_hms $songtime )

Desde songtime consta de un par de números separados por espacios, el shell realiza la división de palabras en el valor de songtime y jc_hms ve dos parámetros separados. Esto no requiere ningún cambio en la definición de jc_hms , y no es necesario canalizar nada a través de la entrada estándar.

Si todavía tiene un motivo diferente para jc_hms para leer la entrada estándar, háganoslo saber.


1) Sé que esta es una publicación bastante antigua

2) Me gustan la mayoría de las respuestas aquí

Sin embargo, encontré esta publicación porque necesitaba algo similar. Si bien todos están de acuerdo en que stdin es lo que debe usarse, lo que falta en las respuestas aquí es el uso real del archivo /dev/stdin.

El uso de read builtin obliga a que esta función se use con entrada canalizada, por lo que ya no se puede usar de una manera típica. Creo que utilizar /dev/stdin es una forma superior de resolver este problema, por lo que quería agregar mis 2 centavos para completar.

Mi solución:

jc_hms() { 
  declare -i i=${1:-$(</dev/stdin)};
  declare hr=$(($i/3600)) min=$(($i/60%60)) sec=$(($i%60));
  printf "%02d:%02d:%02d\n" $hr $min $sec;
}

En acción:

[email protected]:pwd$ jc_hms 7800
02:10:00
[email protected]:pwd$ echo 7800 | jc_hms 
02:10:00

Espero que esto pueda ayudar a alguien.

¡Feliz piratería!


O bien, también puedes hacerlo de forma sencilla.

jc_hms() {
    cat
}

Aunque todas las respuestas hasta ahora han ignorado el hecho de que esto no era lo que OP quería (afirmó que la función está simplificada)


Linux
  1. ¿Dividir la salida del comando por columnas usando Bash?

  2. Usando la salida de comandos anteriores en bash

  3. Bash capturando la salida de awk en una matriz

  4. Especificar la posición de salida de la tubería

  5. ¿Por qué parece que pierdo datos usando esta construcción de tubería bash?

Cómo leer archivos línea por línea en Bash

Bash:escribir en archivo

Comando de lectura Bash

Funciones bash

Cómo leer un archivo línea por línea en Bash

Shell Scripting Parte V:Funciones en Bash