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 3
servem &
?
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>&1
linha de comando criará um novo descritor de arquivo e o redirecionará para 1
o qual é STDOUT
. Agora 1>&2
irá redirecionar o descritor de arquivo 1 para STDERR
e 2>&3
redirecionará o descritor de arquivo 2 para 3, que é STDOUT
.
Então, basicamente você mudou STDOUT
e STDERR
, estas são as etapas:
- Crie um novo fd 3 e aponte-o para o fd 1
- 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.
- 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 stdout
e stderr
.
>name
significa redirecionar a saída para file name
.
>&number
significa 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 0
para entrada padrão, 1
para saída padrão ou 2
para 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 1
quanto 2
o go to /dev/tty
, portanto, se você executar somecommand 3>&1 1>&2 2>&3
em 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 dialog
a saída de 's seja enviada stdout
em vez de stderr
por 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.