Инструмент rename
является крайне непортативным; нет почти ничего общего между версией rename
для семейства RHEL/CentOS/Fedora и версией, найденной в Ubuntu или Debian.
Я написал ответ с примерами использования обеих версий rename
некоторое время назад.
Вы не сказали, какую ОС вы используете, поэтому трудно быть очень конкретным - и поскольку это домашнее задание, вы должны поработать над ним сами, поэтому я не буду писать ответ, даже если вы скажете, какую ОС.
Однако, пара советов:
sed
работает с содержимым текстового файла; он не изменяет имя файла и уж тем более имя каталога. Его нельзя использовать для этого, и именно поэтому вы получаете ошибки от команды, которую вы написали. find
. -name
и -iname
для find
, так как они могут пригодиться (не нужно пытаться переименовывать файлы, которые не соответствуют заданному шаблону). -exec
с rename
(соответствующей версии для вашей ОС), вероятно, является самым простым/лучшим решением для этого. Это зависит от ядра и типа исполняемого файла . Это не зависит от того, как исполняемый файл был запущен или установлен.
В Linux:
Для собственных исполняемых файлов (т. Е. Двоичных файлов, содержащих машинный код, выполняемых непосредственно ядром), исполняемый файл не может быть изменен во время его работы.
$ cp / bin / sleep.
$ ./sleep 999999 &
$ echo> sleep
sh: 1: невозможно создать сон: текстовый файл занят {{1} }
Можно удалить исполняемый файл (т.е. отсоединить его) и создать новый по тому же пути . Как и в любом другом случае, когда файл удаляется, пока он еще открыт, удаление исполняемого файла не влияет на запущенный процесс и фактически не удаляет его с диска до тех пор, пока файл не перестанет использоваться, то есть пока все запущенные экземпляры выход из программы.
Для сценариев (начиная с #!
) файл сценария может быть изменен во время работы программы. Повлияет ли это на программу, зависит от того, как интерпретатор читает сценарий. Если он считывает весь скрипт в свою память перед началом выполнения, это не повлияет на выполнение.Если интерпретатор читает сценарий по запросу, это может повлиять на выполнение; некоторые реализации sh
делают это.
Многие другие системы Unix ведут себя подобным образом, но не все. Более старые версии Solaris IIRC позволяют изменять собственный исполняемый файл, что обычно приводит к его сбою. Некоторые варианты Unix, в том числе HP / UX, даже не позволяют удалить собственный исполняемый файл, который в настоящее время работает.
Большинство программ установки программного обеспечения заботятся об удалении существующего исполняемого файла перед установкой нового на место, в отличие от перезаписи существующего двоичного файла. Например. делать
rm /bin/target
cp target /bin
, а не просто cp target / bin
. Таким образом работает команда оболочки install
. Это не идеально, потому что, если кто-то попытается выполнить / bin / target
во время выполнения процесса cp
, он получит поврежденную программу. Лучше скопировать файл с временным именем, а затем переименовать его в окончательное имя. При переименовании файла (т.е. перемещении его в тот же каталог или, в более общем смысле, перемещении внутри той же файловой системы) удаляется предыдущий целевой файл, если он существует. Так, например, работает dpkg
.
cp target /bin/target.tmp
mv /bin/target.tmp /bin/target
Повлияет ли перезапись исполняемого файла на процесс, в котором запущен исходный исполняемый файл?
обычно нет, насколько я понимаю, когда ядро форкает и запускает новый процесс, исполняемый файл (который содержит программу) считывается и загружается в память.
После этого базовый файл обычно больше не нужен, по крайней мере до следующего раза, когда файл будет прочитан для другого процесса.
Вот почему вам нужно перезагрузить компьютер после того, как обновление заменило базовый файл для системной программы или библиотеки - вы не можете "повлиять на запущенный процесс" (т.е. заменить) новой версией, которая была считана из обновленного файла.
Единственный способ получить новую, обновленную функциональность - остановить запущенный процесс и перезагрузить его из нового файла, но в случае системных программ или самого ядра программу нельзя выключить, как, например, браузер.
Поэтому для того, чтобы прочитать новый - обновленный - файл, необходимо остановить всю систему.
Вы можете попробовать сами:
$ cp /usr/bin/sleep /tmp/sleep
$ /tmp/sleep 20 &
$ truncate -s 1 /tmp/sleep
truncate: cannot open '/tmp/sleep' for writing: Text file busy
Система не позволяет вам изменить запущенный двоичный файл. Однако вы можете разорвать связь с файлом и изменить его:
$ /tmp/sleep 20 &
$ rm /tmp/sleep
$ cp /usr/bin/ls /tmp/sleep
$ [2]- Done /tmp/sleep 20
Обратите внимание, что для сценариев оболочки ядро не защищает сценарий, поскольку занятый двоичный файл - это, например, / bin / bash. Вы не должны перезаписывать файл сценария оболочки, но вы можете удалить его и заменить новым.
Что касается установки обновленных пакетов, то зависит от упаковщика, будет ли запущен запущенный демон или нет.Я не знаю, существует ли соглашение, но я просмотрел несколько примеров скриптлетов rpm в моей системе Fedora, и они, похоже, перезапускаются при обновлении. Например,
$ rpm --scripts -qf /usr/sbin/xinetd
...
postuninstall scriptlet (using /bin/sh):
...
if [ $1 -ge 1 ] ; then
# Package upgrade, not uninstall
systemctl try-restart xinetd.service >/dev/null 2>&1 || :
fi
Обновление пакета rpm -U
запустит новые сценарии до и после установки, а затем старые сценарии до и после удаления. Как видно выше, postuninstall перезапустит службу systemd.
Из комментариев ознакомьтесь также с этим ответом об общих библиотеках и обратите внимание, как изменение интерпретируемых сценариев очень сильно зависит от того, как интерпретатор буферизует или перечитывает файл, или перекомпилирует его в новый файл на летать.