Какой в ​​настоящее время самый эффективный способ "скопировать/вставить" вывод ls в другую команду?

ПРИМЕЧАНИЕ.:Вы, вероятно, захотите использовать 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? )Это должно быть намеком на то, что там происходит.

0
08.05.2020, 22:49
6 ответов

вы должны иметь возможность использовать :ls -lrt | grep (char string )> ваш код. Где строка символов — это имя вашего файла или символы, которые позволят grep найти имя вашего файла.

если бы имя файла было xxx.rhbd.yuv.txt, вы могли бы запустить

лс -лрт | grep rhdb > ваш код.

Если найдено несколько файлов, каждый из них будет отправлен на ваш код.

-1
28.04.2021, 23:15

Ознакомьтесь с 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)
3
28.04.2021, 23:15

Если вы используете bash, вы можете вызватьedit-and-execute-command(см. справочную страницу ). Это заставит bash открыть текущую командную строку в $VISUALили $EDITORпо вашему выбору. Затем вы можете использовать редактор для получения вывода ls.

Это сильно зависит от вашей конфигурации, но по умолчанию C-xC-eделает это. Если у вас bash установлен в режим vi, то esc vсделает это.

Когда вы сохраняете и редактируете свой редактор, bash выполняет команду.

Аналогичные возможности есть и у других оболочек.

0
28.04.2021, 23:15

Вы можете использовать конструкцию selectbash с «свободным» шаблоном подстановочных знаков (даже *), который, как вы уверены, будет включать нужное вам имя файла.

Перейдите в нужный каталог (или полностью -укажите подстановочный знак ), затем:

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
3
28.04.2021, 23:15

Загрузите вывод lsв массив bash, затем отобразите массив с нумерацией строк, а затем используйте номер строки для обращения к выбранной строке. Позвольте мне объяснить шаг за шагом:

  1. прочитать список файлов в массив 'a':

readarray -t < <(ls) a

  1. отображать массив с нумерацией строк, начиная с нуля:

printf '%s\n' "${a[@]}"|nl -v 0

  1. использовать 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
0
28.04.2021, 23:15

Предупреждение

Этот ответ может дать неожиданные результаты, поскольку он зависит от конвейерной передачи вывода 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', чтобы проверить, что в конечном итоге вы получите только один результат, если только вы не уверены, что имя файла уникально.

РЕДАКТИРОВАТЬ 1

Как указал @roaima, если в имени вашего файла есть пробелы,вам нужно будет добавить двойные кавычки к выражению :main_command_to_run "$(ls | grep 'name_of_file')"

Использование подстановочных знаков (подстановка)

Альтернативой использованию синтаксиса $(ls | grep 'name_of_file')может быть подстановка. Подстановочные знаки, такие как '?', '*' и '[]' среди других используются для сопоставления символов.

В качестве примера использования звездочек, звездочка ('*' )представляет собой подстановочный знак, который соответствует нулю или более символов. Таким образом, возможный вариант использования файла с именем «foo.tar.gz», как любезно предоставил @roaima, будет:
tar -xvzf *.tar*

РЕДАКТИРОВАТЬ 2

Как отметил @Hermann, передача вывода lsненадежна по целому ряду причин. См. следующие ссылки для объяснения того, почему:
Ссылка 1
Ссылка 2
Ссылка 3
Ссылка 4

0
28.04.2021, 23:15

Теги

Похожие вопросы