A substituição do processo Bash pode ser usada como parte da expansão de argumentos?

1

Estou familiarizado com a substituição de processo usada da maneira canônica, por exemplo

diff <(ls /folder1) <(ls /folder2)

No entanto, ele pode ser usado quando o processo pede um argumento que não seja apenas o caminho para a expressão? Por exemplo,

curl -XPOST https://host:1234/upload -F data=@$(echo <(head -c1M /dev/urandom))

Isso não funciona porque a substituição interna existe para o processo subshell, não o processo externo; no entanto, é efetivamente o que estou tentando alcançar.

    
por user508633 20.07.2016 / 21:42

1 resposta

2

Quando você usa a sintaxe <(cmd) , o que normalmente acontece é que o "cmd" é executado com stdout conectado a um descritor de arquivo temporário e o nome do arquivo desse descritor retornado, para que possa ser usado como um parâmetro

por exemplo

ksh$ echo <(echo hello)
/dev/fd/4

bash$ echo <(echo hello)
/dev/fd/63

Agora que /dev/fd/## entry só é válido no escopo do shell que está chamando <(..) porque /dev/fd é um link simbólico para /dev/self/fd .

Isso significa que no seu exemplo de data=@$(echo <(head -c1M /dev/urandom)) if será analisado como se você tivesse digitado data=@/dev/fd/63 , mas isso não funcionaria porque o shell que está executando o comando curl não é o shell que tinha a subsituição do processo.

Agora, <(...) pode ser incluído em outras entradas e funcionará, contanto que você não passe os nomes de arquivos temporários

por exemplo, isso não funcionará

$ cat <(echo <(echo hello))
/dev/fd/63

mas isso irá funcionar

$ cat <(cat <(echo hello))
hello

Na sua versão, porém, você tem um nível desnecessário de indireção e deve ser capaz de simplesmente fazer

data=@<(head -c1M /dev/urandom)
    
por 22.07.2016 / 20:51