2012-04-14 19 views
8

En bash que puede hacer:¿hay usos para '> & 0' (redirigir a stdin)?

  • echo test >&1 (redirigir la salida estándar, aunque ya va allí)
  • echo test >&2 (redirección a stderr)
  • echo test >&0 (redirección a la entrada estándar)

Cuando hago el último, mi terminal todavía imprime test como lo haría con los otros dos, pero es difícil saber por qué. Entonces, primero, ¿por qué funciona esto? En segundo lugar, ¿hay algún buen uso para redirigir a stdin?

Respuesta

6

Para ser más preciso, lo que >&0 es el descriptor de archivo duplicado 0 como descriptor de archivo 1. Si el programa stdin está solo abierto para lectura, entonces cuando su programa intente escribir en stdout (descriptor de archivo 1), obtendrá un error porque el descriptor de archivo 1 también está solo abierto para la lectura.

Usted puede demostrar esto escribiendo un pequeño script de shell que inspecciona sus propios descriptores de archivo:

10156115.sh:

#!/bin/bash 
bash -c 'ls -l /proc/$$/fd' >&0 

e invocarla con la entrada estándar de identificación personal, stdout y stderr:

$ touch stdin 
$ ./10156115.sh <stdin> stdout 2> stderr 

el resultado es que se obtiene el siguiente en stderr:

ls: write error: Bad file descriptor 

Sin embargo, por defecto, los tres son una terminal: (salida simplificado)

$ ls -l /proc/$$/fd 
lrwx------ 0 -> /dev/pts/14 
lrwx------ 1 -> /dev/pts/14 
lrwx------ 2 -> /dev/pts/14 
lrwx------ 255 -> /dev/pts/14 

Por lo general, los tres son en realidad abierto de lectura + escribir, por lo que el >&0 redirección no tiene ningún efecto en absoluto si se utiliza solo de un caparazón normal.


¿Hay algún uso para esto?

no hay ninguno de los usos comunes de esto, pero es posible utilizarlo como un truco sucio para conseguir una manera de imprimir en el terminal si quien llama a su script redirige stdout y stderr, y por alguna razón usted no está capaz de cambiar eso:

if [ ! -t /dev/fd/1 -a ! -t /dev/fd/2 -a -t /dev/fd/0 ]; then 
    echo "My message that I really, really want to go to a terminal" >&0 
fi 

Pero no recomendaría realmente hacer esto.

5

Por razones históricas, los descriptores de archivo estándar en un terminal son de lectura/escritura abierta en lugar de de solo lectura (específicamente, se abre una vez y dup() ed a los demás). Esto es ocasionalmente útil para los programas que desean tomar una entrada canalizada pero también leer la entrada del usuario (desde stdout, o más comúnmente stderr), aunque el uso de /dev/tty es más confiable en ese caso. Algunos sistemas aplican esto a algo más que ttys: los * BSD abren socketpairs ("pipes") bidireccionalmente, y algunas utilidades del sistema (recuerdo que ufsdump son un ejemplo) dependen de esto.

Redirigir a stdin (es decir, tener que abrir sólo para escritura) generalmente no es útil, ya que la mayoría de los programas esperan que sea abierto para lectura (o, a veces leer/escribir, como arriba).

Cuestiones relacionadas