J'ai un php
script shell ( ) qui entre en contact avec le fichier cible de cette façon:
- si Inspecte fichier et répertoire sont inscriptibles avec
php
l »is_writable()
(je ne pense pas que ce problème) - modifie le fichier sur place avec la
sed
commande:
grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n"; } || printf "Password not changed!\n"
En conséquence, je reçois (tout le reste est correct, mais) le fichier qui devait myuser:www-data
être myuser:myuser
.
La sed
propriété du groupe de fichiers change- t- elle comme il semble, et comment l'éviter, si possible?
bash
shell
shell-script
permissions
chown
Miloš Đakonović
la source
la source
Réponses:
Il y a un petit problème avec
sed
le mode d'édition sur place-i
.sed
crée un fichier temporaire dans le même répertoire appelésedy08qMA
, oùy08qMA
est une chaîne générée aléatoirement. Ce fichier est rempli avec le contenu modifié du fichier d'origine. Après l'opération,sed
supprime le fichier d'origine et renomme le fichier temporaire avec le nom de fichier d'origine. Ce n'est donc pas une véritable modification in situ . Il crée un nouveau fichier avec les autorisations de l'utilisateur appelant et un nouveau numéro d'inode. Ce comportement n'est généralement pas mauvais, mais par exemple, les liens durs sont rompus.Cependant, si vous souhaitez une véritable édition sur place, vous devez utiliser
ed
. Il lit les commandes de la stdin et édite le fichier directement, sans fichier temporaire (c'est fait sured
le tampon mémoire de). Une pratique courante consiste à utiliserprintf
pour générer la liste de commandes:La
printf
commande produit la sortie comme suit:Ces deux lignes sont des
ed
commandes. Le premier recherche la chaînesearch
et la remplace parreplace
. Le second écrit (w
) les modifications apportées au fichier et quitte (q
).-s
supprime la sortie de diagnostic.la source
Le
-i
paramètresed
fonctionne en créant un fichier temporaire pendant le fonctionnement, puis en remplaçant le fichier réel par le fichier temporaire à la fin. C'est probablement la cause du problème, car lors de la création du propriétaire du fichier temporaire, la valeur par défaut estmyuser:myuser
Vous pouvez définir le
setgid
bit sur le répertoire parent (uniquement si le répertoire parent appartient au groupewww-data
), de sorte que les fichiers créés sous ce répertoire héritent du même groupe.pour faire ça:
Je pense que c'est une utilisation très typique du
setgid
bit.la source
sed -i
, j'ai trouvé la ligne suivante dans la trace, cela signifie-t-il qu'il a créé le fichier temporaire dans le répertoire actuel?open("./sedKyG9Ei", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
L'utilisation de
ed
au lieu desed
semble plutôt superflue pour cela, étant donné que vous devez ajouter une entrée supplémentaire. La distribution sur laquelle je travaille en ce moment (CentOS 5.10) a l'-c
optionsed
qui utilise la «copie» du fichier temporaire plutôt que de simplement le renommer lorsqu'elle est utilisée avec l'-i
option. Je l'ai testé et cela a fonctionné parfaitement, préservant le propriétaire et le groupe d'origine lors d'une modification en ligne. Il ne conserve PAS l'heure de modification.par exemple,
sed -ci -e '3,5d' file.txt
-c
utilise la copie au lieu de renommer (c.-à-d. préserve la propriété / le groupe)-i
édition en ligne-e
script / expression à exécuterJe ne sais pas à quel point cette option est répandue
sed
dans d'autres distributions. Solaris 10 ne l'avait pas, mais Solaris n'a pas beaucoup de choses que je veux.la source