Use >&N
. É portátil e, como você viu, funciona com soquetes.
A única razão pela qual você usaria /proc/self/fd
é que você está executando um programa que espera um nome de arquivo e não pode ser instruído a usar um descritor de arquivo já aberto. Por exemplo. o redirecionamento <(cmd...)
usa isso, já que quase todos os utilitários de linha de comando podem abrir um arquivo apontado pelo nome, mas nem todos os descritores de arquivos pré-abertos suportam diretamente.
Seu shell pode usar descritores de arquivos pré-existentes, portanto, não é necessário passar por /proc
.
Além disso, /proc/NNN/fd/
é específico do Linux e requer que você tenha um /proc
montado. Nas minhas caixas de Linux, /dev/stdout
, /dev/fd/*
e outros são links simbólicos para /proc/self/fd/*
etc., então eles exigem /proc
também. Em outros Unixes, eles podem ser diferentes. De acordo com as respostas para uma pergunta antiga /dev/stdout
estão especificamente listadas como fora do POSIX.
Quanto ao motivo pelo qual o redirecionamento não funciona como você tentou: Experimentando com strace
, a diferença entre os dois é que para um redirecionamento >&N
, bash
chama dup()
no descritor de arquivo e para >/proc/self/fd/N
ele apenas tenta abri-lo como um arquivo comum com open()
. Aparentemente proc
não suporta a abertura de novas cópias de sockets assim, então a chamada falha. Os sockets de stream são basicamente links ponto a ponto, então proibir a abertura de uma nova cópia não parece muito antinatural. Mas por que funciona para pipes ou com dup
, não sei dizer.
$ ls -l /proc/self/fd/3
lrwx------ 1 itvirta itvirta 64 Jul 14 18:24 /proc/self/fd/3 -> socket:[168157]
$ strace bash -c "echo foo >>/proc/self/fd/3" 2>&1 | grep open.*proc/self
open("/proc/self/fd/3", O_WRONLY|O_CREAT|O_APPEND, 0666) = -1 ENXIO (No such device or address)
Também esta resposta tem algumas informações sobre a portabilidade de /proc/NNN/fd