ПРИМЕЧАНИЕ:При написании ниже я использовал OpenBSD find
, в которой -execdir utility {} ';'
заменит {}
базовым именем найденных файлов. В GNU find
{}
также будет базовым именем найденного файла, но к нему будет дополнительно добавляться ./
, что делает первую команду find
ниже бесполезной. Для пользователей GNUfind
(большинство людей на Linux, например ), прокрутите вниз до других вариантов решения.
Вы хотите найти все .c
файлы в каталоге lokesh
или ниже него и добавить к их именам префикс x_
.
find lokesh -type f -name '*.c' -execdir echo mv {} x_{} ';'
Выражения -type f
и -name '*.c'
найдут все соответствующие файлы, а -execdir mv {} x_{} ';'
переименует найденные файлы.
Выражение -execdir
не является стандартным, но большинство реализаций find
поддерживают его. Он отличается от -exec
тем, что данная утилита выполняется с родительским каталогом найденного пути в качестве рабочего каталога. Поэтому {}
в командной строке будет базовым именем файлов, которые мы хотим переименовать (, а не полным путем, как в случае с-exec
).
Запустите это один раз, а затем удалите echo
, когда увидите, что он работает правильно. echo
предотвратит фактическое переименование файлов mv
.
В системах, которые не поддерживают-execdir
(или не поддерживают -execdir
, как это делает OpenBSD):
find lokesh -type f -name '*.c' \
-exec sh -c 'for name do echo mv "$name" "${name%/*}/x_${name##*/}"; done' sh {} +
или, короче, но чуть менее эффективно,
find lokesh -type f -name '*.c' \
-exec sh -c 'echo mv "$1" "${1%/*}/x_${1##*/}"' sh {} ';'
В обоих этих вариантах используется короткий сценарий оболочки, который в конечном итоге делает одно и то же.:
mv "$name" "${name%/*}/x_${name##*/}"
Это перемещает файл с полным путем в $name
на новое имя с префиксом x_
в том же каталоге. Замена параметра ${name%/*}
эквивалентна $( dirname "$name" )
и дает родительский каталог пути, а ${name##*/}
эквивалентна $( basename "$name" )
, который дает базовому имени (компонент имени файла )имени пути.
Похоже, вы получаете сообщение об ошибке использования. apachectl
отвечает так, как если бы вы вызвали его как:
/usr/sbin/apachectl '-M > /home/ciasto/services/logs/apache2/loaded_mods'
Вы можете видеть, что аргументы :-M
, >
,/home/...
Строка ExecStop=
не является sh
и не поддерживает некоторые операторы sh
, такие как &
, >
или |
. Если вы хотите использовать эти операторы, вызовите оболочку напрямую и передайте команду в качестве аргумента:
ExecStop=+/bin/sh -c '/usr/sbin/apachectl -M > /home/ciasto/services/logs/apache2/loaded_mods'
Как вы заметили в комментариях, у вашего сервиса есть User=www-data
. www-data
может не иметь разрешения на выполнение для вещей в sbin
или разрешения на запись для /home/ciasto/*
. Поэтому вам может потребоваться выполнить эту команду (и только эту команду )с правами root, в то время как другие строки по-прежнему будут выполняться как www-data
. Использование ExecStop=+/bin/sh
вместо ExecStop=/bin/sh
сделает это за вас.
Небольшая демонстрация:
User=www-data
ExecStop=/usr/bin/whoami
ExecStop=+/usr/bin/whoami
напишет следующее в журнал:
www-data
root