Vi esta línea en un script:
DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`
Qué es
3>&1 1>&2 2>&3
¿haciendo? Sé que 1 = stdout y 2 = stderr, pero ¿para qué 3
sirven &
?
Respuesta1
Los números son descriptores de archivos y sólo los tres primeros (empezando por cero) tienen un significado estandarizado:
0 - stdin
1 - stdout
2 - stderr
Entonces, cada uno de estos números en su comando se refiere a un descriptor de archivo. Puede redirigir un descriptor de archivo a un archivo con >
o redirigirlo a otro descriptor de archivo con>&
En 3>&1
su línea de comando creará un nuevo descriptor de archivo y lo redirigirá al 1
que es STDOUT
. Ahora 1>&2
redirigirá el descriptor de archivo 1 al STDERR
y 2>&3
redirigirá el descriptor de archivo 2 al 3, que es STDOUT
.
Básicamente cambiaste STDOUT
y STDERR
estos son los pasos:
- Crea un nuevo fd 3 y apúntalo al fd 1
- Redirigir el descriptor de archivo 1 al descriptor de archivo 2. Si no hubiéramos guardado el descriptor de archivo en 3, perderíamos el objetivo.
- Redirija el descriptor de archivo 2 al descriptor de archivo 3. Ahora los descriptores de archivo uno y dos están intercambiados.
Ahora, si el programa imprime algo en el descriptor de archivo 1, se imprimirá en el descriptor de archivo 2 y viceversa.
Respuesta2
Está intercambiando stdout
y stderr
.
>name
significa redirigir la salida al archivo name
.
>&number
significa redirigir la salida al descriptor de archivo number
.
Por lo tanto, &
es necesario decirle al shell que te refieres a un descriptor de archivo, no a un nombre de archivo.
Un descriptor de archivo es un número que hace referencia a un archivo ya abierto. Los estándar son 0
para entrada estándar, 1
para salida estándar o 2
para error estándar. También puedes usar cualquier otro número, lo que creará un nuevo descriptor de archivo, tal como cuando creas una nueva variable con var=value
.
De forma predeterminada, tanto el descriptor de archivo 1
como 2
ir a /dev/tty
, por lo que si ejecuta somecommand 3>&1 1>&2 2>&3
en un nuevo shell, no cambia nada (excepto que ahora tiene un descriptor de archivo número 3).
Pero si en algún lugar anterior del script realiza una redirección usando exec (p. ej. exec 2>error.log
), o el script se ejecuta con una línea de comando que incluye la redirección (p. ej. ./thescript 2>error.log
), entonces intercambiar stdout y stderr hará algo.
En su caso específico, el comando cuyo stdout y stderr se intercambian es dialog
. mirando supágina de manual, Veo
Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error
Entonces, tal vez la persona que escribió el guión quiera dialog
que la salida vaya a stdout
en lugar de stderr
por alguna razón.
Ver tambiénOrden de redirecciones
Respuesta3
El guionista definió fd 3 como:
exec 3<> File.txt
Abra "File.txt" y asígnele fd 3. Descriptores de archivos máximos: 255
read -n 4 <&3
Lee solo 4 caracteres.
echo -n . >&3
Escribe un punto decimal allí.
exec 3>&-
Cerrar fd 3.
cat File.txt
==> 1234.67890
Respuesta4
Entendí el propósito del descriptor de archivo y el comando "3> & 1 1> & 2 2> & 3" con el siguiente ejemplo
#!/bin/bash
#it's normal case fd environment
echo test 1> afile.txt
echo "Test no 1"
cat afile.txt
echo "Test no 1"
echo test 2> afile.txt
echo "Test no 2"
cat afile.txt
echo "Test no 2"
echo test 1> afile.txt
echo "Test no 3"
cat afile.txt
echo "Test no 3"
echo test 2> afile.txt
echo "Test no 4"
cat afile.txt
echo "Test no 4"
echo > afile.txt
echo "------------------------------------------------------------------------"
#it's relocate filedescriptor and cause not problem, and cause error(std error)
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 5"
#cat afile.txt
echo $var
echo "Test no 5"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 6"
#cat afile.txt
echo $var
echo "Test no 6"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 7"
#cat afile.txt
echo $var
echo "Test no 7"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 8"
#cat afile.txt
echo $var
echo "Test no 8"
Cuando ejecute este ejemplo, verá que los descriptores de archivos se reorganizan y la salida cambia.