У меня есть php
скрипт shell ( ), который связывается с целевым файлом следующим образом:
- проверяет, можно ли записать файл и каталог с помощью
php
sis_writable()
(я не думаю, что это проблема) - выполняет редактирование файла на месте с помощью
sed
команды:
grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n"; } || printf "Password not changed!\n"
В результате я получаю (все остальное правильно, но) файл, который должен myuser:www-data
был быть myuser:myuser
.
Изменяет ли sed
владение файловую группу, как кажется, и как мне избежать этого, если это возможно?
bash
shell
shell-script
permissions
chown
Милош Чаконович
источник
источник
Ответы:
Существует небольшая проблема с
sed
режимом редактирования на месте-i
.sed
создает временный файл в том же каталогеsedy08qMA
, где иy08qMA
находится случайно сгенерированная строка. Этот файл заполнен измененным содержимым исходного файла. После операцииsed
удаляет исходный файл и переименовывает временный файл с исходным именем файла. Так что это не настоящее редактирование на месте . Он создает новый файл с разрешениями вызывающего пользователя и новым номером инода. Такое поведение в основном неплохое, но, например, жесткие ссылки нарушаются.Однако, если вы хотите истинное редактирование на месте, вы должны использовать
ed
. Он читает команды из стандартного ввода и редактирует файл напрямую, без временного файла (это делается черезed
буфер памяти). Обычной практикой является использованиеprintf
для генерации списка команд:Команда
printf
производит вывод следующим образом:Эти две строки являются
ed
командами. Первый ищет строкуsearch
и заменяет ее наreplace
. Второй пишет (w
) изменения в файле и выходит (q
).-s
подавляет диагностический вывод.источник
-i
Параметрsed
работ пути создания временного файла во время работы, а затем перезаписать сам файл с временным файлом в конце. Это наиболее вероятная причина проблемы, так как при создании временного файла владельца по умолчаниюmyuser:myuser
Вы можете установить
setgid
бит в родительском каталоге (только если родительский каталог принадлежит группеwww-data
), чтобы файлы, созданные в этом каталоге, наследовали одну и ту же группу.сделать это:
Я думаю, что это очень типичное использование
setgid
бита.источник
sed -i
, нашел следующую строку в трассировке, означает ли это, что он создал временный файл в текущем каталоге?open("./sedKyG9Ei", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
Использование
ed
вместо вместо этогоsed
кажется довольно излишним, учитывая, что вам нужно добавить дополнительный ввод. В дистрибутиве, над которым я сейчас работаю (CentOS 5.10), есть-c
опция,sed
которая использует «копирование» временного файла, а не просто переименовывает его при использовании с этой-i
опцией. Я протестировал его, и он отлично работал, сохранив первоначального владельца и группу при выполнении встроенного редактирования. Это НЕ сохраняет время модификации.например,
sed -ci -e '3,5d' file.txt
-c
использует копию вместо переименования (то есть сохраняет собственность / группу)-i
встроенное редактирование-e
скрипт / выражение для выполненияНе уверен, насколько распространен этот параметр для
sed
других дистрибутивов. У Solaris 10 его не было, но у Solaris не так много вещей, которые я хочу.источник