Eu uso o Bash 4.3.48(1) no Ubuntu 16.04 (xenial) com uma pilha LEMP.
Eu tento criar um php.ini
arquivo de substituição de forma independente de versão com printf
.
1) A operação independente de versão falha:
printf "[PHP]\n post_max_size = 200M\n upload_max_filesize = 200M\n cgi.fix_pathinfo = 0" > /etc/php/*/fpm/zz_overrides.ini
O seguinte erro é dado:
bash: /etc/php/*/zz_overrides.ini: Arquivo ou diretório inexistente
2) A operação gnóstica da versão é bem-sucedida:
printf "[PHP]\n post_max_size = 200M\n upload_max_filesize = 200M\n cgi.fix_pathinfo = 0" > /etc/php/7.0/fpm/zz_overrides.ini
Como você pode ver, ambos são basicamente idênticos, exceto *
vs.7.0
- Não encontrei nenhuma pista sobre esse problema (regex?) em
man printf
. - Pesquisei no Google e não encontrei nada sobre "permitir regex em printf".
Por que a operação independente de versão falha e há algum desvio?
Edit: Se possível, é mais importante para mim usar uma operação de uma linha.
O comportamento de uma correspondência de padrão em um redirecionamento parece diferir entre os shells. Dos que estão no meu sistema, traço e ksh93 não expandem o padrão, então você obtém um nome de arquivo com uma extensão
*
. Bash o expande (1) , mas apenas se o padrão corresponder a um arquivo. Ele reclama se houver mais nomes de arquivos correspondentes. O Zsh funciona como se você desse vários redirecionamentos, ele redireciona a saída para todos os arquivos correspondentes.(1) exceto quando não é interativo e no modo POSIX
Se você deseja que a saída vá para todos os arquivos correspondentes, pode usar
tee
:Se você quiser que ele vá para apenas um arquivo, o problema é decidir qual deles usar. Se você quiser verificar se há apenas um arquivo que corresponde ao padrão, expanda toda a lista e conte-os.
Em bash/ksh:
No shell padrão,
set
os parâmetros posicionais e usam$#
para a contagem.Obviamente, se o padrão não corresponder a nenhum arquivo, ele é deixado como está e, como o glob está no meio, o resultado aponta para um diretório inexistente. É o mesmo que tentar criar
/path/to/file
, antes de/path/to
existir, só que aqui temos/path/*
, literalmente, com o asterisco.Para lidar com isso, você teria que expandir o(s) nome(s) do diretório sem o nome do arquivo e, em seguida, anexar o nome do arquivo a todos os diretórios. Isso é meio feio...
e então podemos usar esse array:
Ou podemos pegar o caminho mais fácil e fazer um loop sobre o padrão de nome de arquivo. É um pouco insatisfatório no caso mais geral, pois requer a execução do comando principal uma vez para cada arquivo de saída ou o uso de um arquivo temporário para armazenar a saída.