Redirecionando stdout e stderr de linhas específicas

1

Estou lendo um arquivo e redirecionando toda a saída para um arquivo. Eu gostaria de redirecionar stdout e stderr de certas expressões para a tela como mostrado abaixo (apenas um exemplo):

#!/bin/bash
OLDIFS=$IFS
while IFS='|'
while read fname fpath dname dpath ; do
echo "$fname" >> redirect to screen
echo "$fpath"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >> redirect to screen
done > logfile

Eu tentei >$(tty) , mas isso não funcionou. Isso não funcionou:

while read fname fpath dname dpath; do
echo "$fname" >&1
echo "$fpath"
echo "$dname"
echo "$dpath"
diff "$fpath/$fname" "$dpath/$dname" >&1
done > logfile

Não consigo usar tee porque redireciona a saída inteira para a tela. Como posso conseguir isso?

    
por Menon 07.04.2015 / 11:15

2 respostas

2

Seu while loop não é interativo, portanto, não tem um tty. Você tem que salvar seu dispositivo tty antes de entrar no loop. Então você teria algo como:

my_tty=$(tty)

while read fname fpath dname dpath ; do
  echo "$fname" | tee ${my_tty}
  echo "$fpath"
  echo "$dpath"
  diff "$fpath/$fname" "$dpath/$dname" | tee ${my_tty}
done > logfile
    
por 07.04.2015 / 11:48
3
while …; do
  echo "$fname" >&1
done > logfile

A saída padrão do comando echo é redirecionada para sua saída padrão. Em outras palavras, >&1 é um não-op. O 1 em >&1 designa o descritor de arquivo 1 do comando em que ele é usado, não de algum escopo externo misteriosamente escolhido.

Para redirecionar para um arquivo que está disponível em um escopo externo, duplique o descritor de arquivo nesse escopo externo e não redirecione o descritor de arquivo duplicado.

while read fname fpath dname dpath; do
  echo "$fname" >&3
  echo "$fpath"
  echo "$dname"
  echo "$dpath"
  diff "$fpath/$fname" "$dpath/$dname" >&3
done 3>&1 >logfile

Observe a ordem dos redirecionamentos no loop: primeiro crie um descritor de arquivo 3 que vá para onde o descritor de arquivo 1 (saída padrão) está indo atualmente e, em seguida, redirecione o descritor de arquivo 1 para outro lugar.

Alternativamente, você pode abrir o arquivo de log em um descritor diferente.

while read fname fpath dname dpath; do
  echo "$fname"
  echo "$fpath" >&3
  echo "$dname" >&3
  echo "$dpath" >&3
  diff "$fpath/$fname" "$dpath/$dname"
done 3>logfile
    
por 08.04.2015 / 01:49