Primeiro, minha solução sugerida é apresentada abaixo. Depois disso, cada um dos dois erros que você observou são discutidos.
Solução sugerida
As variáveis de bash não podem conter um caractere NUL. Consequentemente, só é possível ler um arquivo inteiro em uma variável bash se o arquivo não contiver tais caracteres. Sujeito a esta limitação bash, o seguinte deve funcionar para você:
$ echo aaa | { read -rd "" v; echo "$v"; }
aaa
Com read -d '' var
, o bash lerá stdin até que um caractere NUL seja encontrado. Como as variáveis bash não podem conter caracteres NUL, essa abordagem não limita você além das limitações inerentes do bash.
A opção -r
para read
impede que o bash interprete as seqüências de barra invertida. Além disso, se você deseja preservar espaços em branco iniciais e finais, adicione IFS=
antes da instrução read
.
"tente ler de fd: falha silenciosamente"
# echo aaa | sudo -u nobody bash -c 'echo $(<&0)'
#
A falha silenciosa acima ocorre mesmo sem sudo:
$ echo aaa | bash -c 'echo $(<&0)'
$
Até acontece sem criar o subshell:
$ echo aaa | echo $(<&0)
$
O problema é que &0
não é um nome de arquivo válido. Observe:
$ echo aaa | cat &0
[1] 22635
bash: 0: command not found
No bash, &0
só é significativo quando combinado com <
ou >
.
Vamos ver novamente a documentação do bash:
The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).
Como cat &0
não funciona, não se deve esperar que $(< &0)
funcione.
"usuário diferente. falha"
Isso pode parecer uma coisa razoável de se fazer:
# echo aaa | sudo -u nobody bash -c 'echo $(cat /dev/stdin)'
cat: /dev/stdin: Permission denied
Para ver por que ele falha, vamos examinar as permissões de /dev/stdin
:
# echo aaa | sudo -u nobody bash -c 'ls -lH /dev/stdin'
prw------- 1 root root 0 Jul 1 15:42 /dev/stdin
O usuário não tem permissão para acessar esse arquivo. Isso é razoável: não se quer que ninguém mexa nos arquivos do root.
Um sistema operacional 'mais inteligente' pode saber que ninguém tem acesso a /dev/stdin
neste caso particular mas, por questões de segurança, provavelmente é bom que o sistema operacional não tente inteligente em si.