¿Qué hace "3>&1 1>&2 2>&3" en un script?

¿Qué hace "3>&1 1>&2 2>&3" en un script?

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é 3sirven &?

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>&1su línea de comando creará un nuevo descriptor de archivo y lo redirigirá al 1que es STDOUT. Ahora 1>&2redirigirá el descriptor de archivo 1 al STDERRy 2>&3redirigirá el descriptor de archivo 2 al 3, que es STDOUT.

Básicamente cambiaste STDOUTy STDERRestos son los pasos:

  1. Crea un nuevo fd 3 y apúntalo al fd 1
  2. 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.
  3. 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 stdouty stderr.

>namesignifica redirigir la salida al archivo name.

>&numbersignifica 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 0para entrada estándar, 1para salida estándar o 2para 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 1como 2ir a /dev/tty, por lo que si ejecuta somecommand 3>&1 1>&2 2>&3en 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 dialogque la salida vaya a stdouten lugar de stderrpor 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.

información relacionada