O que "3>&1 1>&2 2>&3" faz em um script?

O que "3>&1 1>&2 2>&3" faz em um script?

Eu vi esta linha em um script:

DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das 
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`

O que é

3>&1 1>&2 2>&3

fazendo? Eu sei que 1 = stdout e 2 = stderr, mas para que 3servem &?

Responder1

Os números são descritores de arquivos e apenas os três primeiros (começando com zero) têm um significado padronizado:

0 - stdin
1 - stdout
2 - stderr

Portanto, cada um desses números no seu comando refere-se a um descritor de arquivo. Você pode redirecionar um descritor de arquivo para um arquivo >ou redirecioná-lo para outro descritor de arquivo com>&

A 3>&1linha de comando criará um novo descritor de arquivo e o redirecionará para 1o qual é STDOUT. Agora 1>&2irá redirecionar o descritor de arquivo 1 para STDERRe 2>&3redirecionará o descritor de arquivo 2 para 3, que é STDOUT.

Então, basicamente você mudou STDOUTe STDERR, estas são as etapas:

  1. Crie um novo fd 3 e aponte-o para o fd 1
  2. Redirecione o descritor de arquivo 1 para o descritor de arquivo 2. Se não tivéssemos salvo o descritor de arquivo em 3, perderíamos o alvo.
  3. Redirecione o descritor de arquivo 2 para o descritor de arquivo 3. Agora os descritores de arquivo um e dois são trocados.

Agora, se o programa imprimir algo no descritor de arquivo 1, será impresso no descritor de arquivo 2 e vice-versa.

Responder2

Está trocando stdoute stderr.

>namesignifica redirecionar a saída para file name.

>&numbersignifica redirecionar a saída para o descritor de arquivo number.

Portanto, &é necessário informar ao shell que você se refere a um descritor de arquivo, não a um nome de arquivo.

Um descritor de arquivo é um número que se refere a um arquivo já aberto. Os padrões são 0para entrada padrão, 1para saída padrão ou 2para erro padrão. Você também pode usar qualquer outro número, que criará um novo descritor de arquivo, assim como quando você cria uma nova variável com var=value.

Por padrão, tanto o descritor de arquivo 1quanto 2o go to /dev/tty, portanto, se você executar somecommand 3>&1 1>&2 2>&3em um novo shell, isso não mudará nada (exceto que agora você tem um descritor de arquivo número 3).

Mas se em algum lugar anterior do script ele fizer um redirecionamento usando exec (por exemplo exec 2>error.log), ou o script for executado com uma linha de comando incluindo redirecionamento (por exemplo ./thescript 2>error.log), a troca de stdout e stderr fará alguma coisa.

No seu caso específico, o comando que está tendo seus stdout e stderr trocados é dialog. Olhando para o seupágina de manual, Eu vejo

Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error

então talvez a pessoa que escreveu o script queira que dialoga saída de 's seja enviada stdoutem vez de stderrpor algum motivo.

Veja tambémOrdem de redirecionamentos

Responder3

O roteirista definiu fd 3 como:

exec 3<> File.txt

Abra "File.txt" e atribua fd 3 a ele. Máximo de descritores de arquivo: 255

read -n 4 <&3

Leia apenas 4 caracteres.

echo -n . >&3

Escreva um ponto decimal ali.

exec 3>&-

Fechar fd 3.

cat File.txt

==> 1234.67890

Responder4

Entendi o propósito do descritor de arquivo e do comando "3> & 1 1> & 2 2> & 3" pelo exemplo abaixo

#!/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"

Ao executar este exemplo, você verá que os descritores de arquivo são reorganizados e a saída muda.

informação relacionada