Uso Bash 4.3.48(1) in Ubuntu 16.04 (xenial) con uno stack LEMP.
Provo a creare un php.ini
overrides in modo indipendente dalla versione con printf
.
1) L'operazione indipendente dalla versione non riesce:
printf "[PHP]n post_max_size = 200Mn upload_max_filesize = 200Mn cgi.fix_pathinfo = 0" > /etc/php/*/fpm/zz_overrides.ini
Viene visualizzato il seguente errore:
bash:/etc/php/*/zz_overrides.ini:nessun file o directory di questo tipo
2) L'operazione gnostica della versione ha esito positivo:
printf "[PHP]n post_max_size = 200Mn upload_max_filesize = 200Mn cgi.fix_pathinfo = 0" > /etc/php/7.0/fpm/zz_overrides.ini
Come puoi vedere, entrambi sono sostanzialmente identici oltre a *
rispetto a 7.0
.
- Non ho trovato la minima idea di questo problema (regex?) in
man printf
. - Ho cercato su Google e non ho trovato nulla su "consentire l'espressione regolare in printf".
Perché l'operazione indipendente dalla versione non riesce ed è presente un bypass?
Modifica:se possibile, è molto importante per me utilizzare un'operazione su una riga.
Risposta accettata:
Il comportamento di una corrispondenza di pattern in un reindirizzamento sembra differire tra le shell. Di quelli sul mio sistema, dash e ksh93 non espandono il modello, quindi ottieni un nome file con un *
letterale . Bash lo espande, ma solo se il modello corrisponde a un file. Si lamenta se ci sono più nomi di file che corrispondono. Zsh funziona come se avessi fornito più reindirizzamenti, reindirizza l'output a tutti file corrispondenti.
(1) tranne quando non è interattivo e in modalità POSIX
Se vuoi che l'output vada a tutti i file corrispondenti, puoi usare tee
:
echo ... | tee /path/*/file > /dev/null
Se vuoi che vada su un solo file, il problema è decidere quale usare. Se vuoi verificare che ci sia un solo file che corrisponde al modello, espandi l'intero elenco e contali.
In bash/ksh:
names=(/path/*/file)
if [ "${#names[@]}" -gt 1 ] ; then
echo "there's more than one"
else
echo "there's only one: ${names[0]}"
fi
Nella shell standard, set
i parametri posizionali e usa $#
per il conteggio.
Ovviamente, se il modello non corrisponde a nessun file, viene lasciato così com'è e poiché il glob si trova nel mezzo, il risultato punta a una directory inesistente. È come provare a creare /path/to/file
, prima di /path/to
esiste, è solo qui che abbiamo /path/*
invece, letteralmente, con l'asterisco.
Per far fronte a ciò, dovresti espandere i nomi delle directory senza il nome del file, quindi aggiungere il nome del file a tutte le directory. Questo è un po' brutto...
dirs=(/path/*)
files=( "${dirs[@]/%//file}" )
e quindi possiamo usare quell'array:
echo ... | tee "${files[@]}" > /dev/null
Oppure potremmo prendere la via più semplice e scorrere il modello del nome del file. È un po' insoddisfacente nel caso più generale, poiché richiede l'esecuzione del comando principale una volta per ogni file di output o l'utilizzo di un file temporaneo per contenere l'output.
for dir in /path/* ; do
echo ... > "$dir/file"
done