Alguns shells, como bash
, suportam a Substituição de Processo, que é uma maneira de apresentar a saída do processo como um arquivo, assim:
$ diff <(sort file1) <(sort file2)
No entanto, essa construção não é POSIX e, portanto, não é portátil. Como a substituição do processo pode ser realizada de maneira amigável ao POSIX (ou seja, uma que funcione /bin/sh
) ?
nota: a pergunta não está perguntando como diferenciar dois arquivos classificados - esse é apenas um exemplo artificial para demonstrar a substituição do processo !
shell
pipe
posix
process-substitution
starfry
fonte
fonte
/bin/sh
ser um shell POSIX, apenas que exista um comando chamado emsh
algum lugar que, no ambiente certo, seja compatível com POSIX. Por exemplo, no Solaris 10,/bin/sh
não é um shell POSIX, é um Bourne shell antigo eo shell POSIX está em/usr/xpg4/bin/sh
.Respostas:
Esse recurso foi introduzido por
ksh
(documentado pela primeira vez no ksh86) e estava usando o/dev/fd/n
recurso (adicionado de forma independente em alguns sistemas BSDs e AT&T anteriormente). Noksh
e até o ksh93u, ele não funcionaria, a menos que seu sistema tivesse suporte para / dev / fd / n. zsh, bash eksh93u+
acima podem fazer uso de pipes nomeados temporários (pipes nomeados adicionados ao SysIII, acredito), onde / dev / fd / n não estão disponíveis.Nos sistemas em que está disponível (o POSIX não os especifica), você pode fazer a substituição do processo por conta própria ( ) com:
/dev/fd/n
diff <(cmd1) <(cmd2)
No entanto, isso não funciona
ksh93
no Linux, pois os shell pipes são implementados com socketpairs em vez de pipes e a abertura/dev/fd/3
onde fd 3 aponta para um soquete não funciona no Linux.Embora o POSIX não especifique . Ele especifica pipes nomeados. Os pipes nomeados funcionam como os pipes normais, exceto que você pode acessá-los no sistema de arquivos. O problema aqui é que você precisa criar arquivos temporários e limpar depois, o que é difícil de ser feito com segurança, especialmente considerando que o POSIX não possui mecanismo padrão (como o encontrado em alguns sistemas) para criar arquivos ou diretórios temporários e manipular sinais de maneira portável (limpar após desligar ou matar) também é difícil de executar de forma portável.
/dev/fd/n
mktemp -d
Você poderia fazer algo como:
(não cuidando da manipulação do sinal aqui).
fonte
/dev/fd/n
exemplo. Por que o descritor 4 é fechado duas vezes? (E o descritor 3 também.) Estou perdido.cmd2
(dup2(0,4)
no exterior{...}
, restaurado comdup2(4,0)
pelo interior{...}
).mktemp -d
ajudar a garantir que você possa obter FIFOs, pois ninguém deve escrever no seu novo diretório temporário aleatório.mktemp -d
. Mas esse não é um comando padrão / POSIX.Se necessário, para evitar a perda de variável no útil
cmd | while read A B C
, em vez de:você pode usar:
Então, para responder à pergunta:
fonte