Sed с редактированием inplace изменяет групповое владение файлом

У меня есть сценарий оболочки ( php ), который так или иначе входит в контакт с целевым файлом:

  • проверяет, доступны ли файлы и каталоги с помощью php 's is_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 изменяет владельца группы файлов, и как мне его избежать, если это возможно?

2 Solutions collect form web for “Sed с редактированием inplace изменяет групповое владение файлом”

Существует небольшая проблема с режимом редактирования sed режиме -i . sed создает временный файл в том же каталоге, что и sedy08qMA , где y08qMA – произвольно сгенерированная строка. Этот файл заполняется измененным содержимым исходного файла. После операции sed удаляет исходный файл и переименовывает временный файл с исходным именем файла. Так что это не настоящая редакция inplace . Он создает новый файл с разрешениями вызывающего пользователя и новый номер inode. Это поведение в большинстве случаев неплохое, но, к примеру, жесткие ссылки нарушаются.

Однако, если вы хотите правдивое редактирование inplace, вы должны использовать ed . Он считывает команды из stdin и редактирует файл напрямую, без временного файла (это делается через буфер памяти ed ). Общей практикой является использование printf для создания списка команд:

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

Команда printf выводит результат следующим образом:

 1,$s/search/replace/g wq 

Эти две строки – это команды ed . Первый ищет поиск строк и заменяет его replace . Второй записывает ( w ) изменения в файл и завершает работу ( q ). -s подавляет диагностический выход.

Параметр -i sed работает, создавая временный файл во время работы, а затем перезаписывает фактический файл временным файлом в конце. Это наиболее вероятно причина проблемы, поскольку при создании файла temp по умолчанию используется myuser:myuser

Вы можете установить бит setgid в родительском каталоге (только если родительский каталог принадлежит группе www-data ), так что файлы, созданные в этом каталоге, наследуют одну и ту же группу.
для этого:

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

Я думаю, что это очень типичное использование бит setgid .

  • Как сделать скрипт sudo без пароля для любого пользователя в bash
  • bash scripting - wget или curl-файл с действием на основе состояния 200 или нет
  • Ожидайте в bash скрипт?
  • Триггер Bash до смерти
  • Почему я получаю «строка 1: $ ': \ r': command not found"?
  • Пытаться направить содержимое переменной в команду дает Ambigious Redirect
  • Использовать выходные данные в качестве переменной в арифметическом вычислении
  • Как zgrep несколько строк
  • Команда mv с шаблоном пути, содержащим случайную строку
  • Более элегантное повторение нескольких массивов bash параллельно
  • Как сравнить два числа
  • Linux и Unix - лучшая ОС в мире.