ПРИМЕЧАНИЕ.:Вы, вероятно, захотите использовать ExecStopPost=
вместо OnFailure=
здесь (см. мой другой ответ ), но это попытка решить, почему ваша установка OnFailure=
не работает.
Проблема с тем, что OnFailure=
не запускает модуль, может быть связана с тем, что он находится в неправильном разделе, он должен быть в разделе [Unit]
, а не [Service]
.
Вместо этого вы можете попробовать:
# software.service
[Unit]
Description=Software
OnFailure=software-fail.service
[Service]
ExecStart=/bin/run_program
И:
# software-fail.service
[Unit]
Description=Delete corrupt files
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service
Я могу заставить его работать с этой настройкой.
Но обратите внимание, что использование OnFailure=
здесь не идеально, так как вы не можете точно сказать, почему программа не удалась, и цепочка другого запуска в ExecStop=
путем прямого вызова /bin/systemctl start
довольно хакерская... решение с использованием ExecStopPost=
и просмотром статуса выхода определенно лучше.
Если вы определяете OnFailure=
внутри [Service]
,systemd (по крайней мере версия 234 из Fedora 27 )жалуется на:
software.service:6: Unknown lvalue 'OnFailure' in section 'Service'
Не знаю, видите ли вы это в своих журналах или нет... (Может быть, это было добавлено в недавней версии systemd? )Это должно быть намеком на то, что там происходит.
вы должны иметь возможность использовать :ls -lrt | grep (char string )> ваш код. Где строка символов — это имя вашего файла или символы, которые позволят grep найти имя вашего файла.
если бы имя файла было xxx.rhbd.yuv.txt, вы могли бы запустить
лс -лрт | grep rhdb > ваш код.
Если найдено несколько файлов, каждый из них будет отправлен на ваш код.
Ознакомьтесь с fzf
. Он идеально подходит для таких задач, как поиск -одного -совпадения -в --большом -списке.
# Launches an interactive selector listing all the contents of the current
# directory and prints the selected item, storing it in $result
$ result=$(ls | fzf)
Если вы используете bash, вы можете вызватьedit-and-execute-command
(см. справочную страницу ). Это заставит bash открыть текущую командную строку в $VISUAL
или $EDITOR
по вашему выбору. Затем вы можете использовать редактор для получения вывода ls.
Это сильно зависит от вашей конфигурации, но по умолчанию C-xC-e
делает это. Если у вас bash установлен в режим vi, то esc v
сделает это.
Когда вы сохраняете и редактируете свой редактор, bash выполняет команду.
Аналогичные возможности есть и у других оболочек.
Вы можете использовать конструкцию select
bash с «свободным» шаблоном подстановочных знаков (даже *
), который, как вы уверены, будет включать нужное вам имя файла.
Перейдите в нужный каталог (или полностью -укажите подстановочный знак ), затем:
select mine in *
do
your-command "$mine"
done
Введите число, соответствующее нужному файлу, и bash выполнит вашу команду с этим именем файла в качестве аргумента. Вспеньте, смойте и повторите столько раз, сколько хотите, затем нажмите Control -D, чтобы завершить цикл select
. Конечно, если вы лучше представляете имя файла, вы можете подставить подстановочный знак.
Использование select
защищает имя файла от непреднамеренного расширения или разделения, которые вы рискуете скопировать/вставить с помощью мыши. В первом случае рассмотрим каталог с двумя файлами:ab
и ab*
. Если вы скопируете/вставите файл ab*
, вместо этого вы получите оба файла , причем сначала ab
! Для последнего рассмотрим каталог с тремя файлами: a
, b
и "a b
". Если вы попытаетесь скопировать/вставить файл «a b
», вместо этого вы передадите другие файлы, a
и b
!
Если вам кажется, что вы слишком много печатаете, вы можете преобразовать его в «один -лайнер»:
select mine in *; do your-command "$mine"; done
Загрузите вывод ls
в массив bash, затем отобразите массив с нумерацией строк, а затем используйте номер строки для обращения к выбранной строке. Позвольте мне объяснить шаг за шагом:
readarray -t < <(ls) a
printf '%s\n' "${a[@]}"|nl -v 0
x
-ю строку из массива:./start_my_prog "${a[x]}"
Пример:
$ ls -l # just to show my example files in the directory
total 0
-rw-rw-r-- 1 chris chris 0 May 8 22:48 file1
-rw-rw-r-- 1 chris chris 0 May 8 22:48 'file 2 with spaces'
-rw-rw-r-- 1 chris chris 0 May 8 22:48 "LongFile-name-don't remember.txt"
-rw-rw-r-- 1 chris chris 0 May 8 22:48 something-else.txt
$ readarray -t < <(ls) a
$ printf '%s\n' "${a[@]}"|nl -v 0
0 file1
1 file 2 with spaces
2 LongFile-name-don't remember.txt
3 something-else.txt
$ echo "${a[2]}"
LongFile-name-don't remember.txt
Вы сами можете создать псевдоним для таких команд:
alias myls='readarray -t < <(ls) a; printf "%s\n" "${a[@]}"|nl -v 0'
И использовать:
$ myls
0 file1
1 file 2 with spaces
2 LongFile-name-don't remember.txt
3 something-else.txt
$ echo ${a[1]}
file 2 with spaces
Этот ответ может дать неожиданные результаты, поскольку он зависит от конвейерной передачи вывода ls
, что не рекомендуется. Для получения подробной информации прокрутите вниз до раздела с пометкой Редактировать 2 .
Подстановка команд$(command)
создаст подоболочку, выполнит команду в подоболочке, а затем вернет вывод подоболочки в основную оболочку.
Синтаксис будет следующим::
main_command_to_run $(ls | grep 'name_of_file')
Обычный вариант использования (для меня по крайней мере )— когда я распаковываю файлы tar.gz.
tar -xvzf $(ls | grep 'tar')
Некоторый контекст -В этом случае я знаю, что в текущем каталоге есть только один файл tar, поэтому мне не нужно вводить полное имя файла tar.gz
Конечно, было бы неплохо сначала запустить ls | grep 'name_of_file'
, чтобы проверить, что в конечном итоге вы получите только один результат, если только вы не уверены, что имя файла уникально.
Как указал @roaima, если в имени вашего файла есть пробелы,вам нужно будет добавить двойные кавычки к выражению :main_command_to_run "$(ls | grep 'name_of_file')"
Альтернативой использованию синтаксиса $(ls | grep 'name_of_file')
может быть подстановка. Подстановочные знаки, такие как '?', '*' и '[]' среди других используются для сопоставления символов.
В качестве примера использования звездочек, звездочка ('*' )представляет собой подстановочный знак, который соответствует нулю или более символов. Таким образом, возможный вариант использования файла с именем «foo.tar.gz», как любезно предоставил @roaima, будет:tar -xvzf *.tar*
Как отметил @Hermann, передача вывода ls
ненадежна по целому ряду причин. См. следующие ссылки для объяснения того, почему:
Ссылка 1
Ссылка 2
Ссылка 3
Ссылка 4