Sed con modifica sul posto cambia la proprietà del gruppo del file


8

Ho uno phpscript shell ( ) che entra in contatto con il file di destinazione in questo modo:

  • ispeziona sia di file e directory scrivibili con php's is_writable()(non credo che questo sia un problema)
  • modifica il file sul posto con il sedcomando:

grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n"; } || printf "Password not changed!\n"

Di conseguenza ottengo (tutto il resto corretto ma) il file che doveva myuser:www-dataessere myuser:myuser.

Non sedcambia file di proprietà del gruppo come sembra, e come devo fare per evitare, se possibile?


Risposte:


16

C'è un piccolo problema con sedla modalità di modifica sul posto -i. sedcrea un file temporaneo nella stessa directory chiamata sedy08qMA, dove si y08qMAtrova una stringa generata casualmente. Quel file viene riempito con il contenuto modificato del file originale. Dopo l'operazione, sedrimuove il file originale e rinomina il file temporaneo con il nome file originale. Quindi non è una vera modifica sul posto . Crea un nuovo file con le autorizzazioni dell'utente chiamante e un nuovo numero di inode. Tale comportamento non è per lo più male, ma ad esempio i collegamenti fisici vengono interrotti.

Tuttavia, se si desidera una vera modifica sul posto, è necessario utilizzare ed. Legge i comandi dallo stdin e modifica il file direttamente, senza un file temporaneo (viene eseguito tramite edil buffer di memoria). Una pratica comune è utilizzare printfper generare l'elenco dei comandi:

printf "%s\n" '1,$s/search/replace/g' wq | ed -s file

Il printfcomando produce output come segue:

1,$s/search/replace/g
wq

Queste due linee sono edcomandi. Il primo cerca la stringa searche la sostituisce con replace. Il secondo scrive ( w) le modifiche al file ed esce ( q). -ssopprime l'output diagnostico.


8

Il -iparametro di sedfunziona creando un file temporaneo durante il funzionamento, quindi sovrascrive il file effettivo con il file temporaneo alla fine. Questa è la causa più probabile del problema, poiché per impostazione predefinita la proprietà del file temporaneo è impostata sumyuser:myuser

È possibile impostare il setgidbit nella directory principale (solo se la directory principale appartiene al gruppo www-data), in modo che i file creati in questa directory ereditino lo stesso gruppo.
fare quello:

chmod g+s parent-dir-of-your-file  

Penso che questo sia un uso molto tipico del setgidbit.


@cuonglm Ho appena fatto una sed -itraccia, ho trovato la seguente riga nella traccia, significa che ha creato il file temporaneo nella directory corrente? open("./sedKyG9Ei", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
Dave.d,

@DavidDai: Sì, il mio mis-memory.
cuonglm,

2

L'uso di al edposto di sedsembra piuttosto superfluo per questo, dato che devi inserire un input aggiuntivo. La distro su cui sto lavorando in questo momento (CentOS 5.10) ha l' -copzione per sedcui utilizza la 'copia' del file temporaneo piuttosto che semplicemente rinominarlo quando usato con l' -iopzione. L'ho provato e ha funzionato perfettamente, preservando il proprietario e il gruppo originali quando si esegue una modifica in linea. NON conserva i tempi di modifica.

per esempio, sed -ci -e '3,5d' file.txt

  • -c utilizza la copia anziché la ridenominazione (ovvero conserva proprietà / gruppo)
  • -i modifica in linea
  • -e script / espressione da eseguire

Non sono sicuro di quanto sia diffusa questa opzione per sedaltre distro. Solaris 10 non ce l'aveva, ma Solaris non ha molte cose che voglio.


Sembra abbastanza utile. Tuttavia, non in Ubuntu 14.04, FWIW. :-(
John Rix,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.