Заставить Bash отправить эту ошибку в стандартную ошибку

find ~/ -type f -print0 2>/dev/null | 
  awk -F/ 'BEGIN {RS=ORS="\0"};
           {
             d=gensub("/[^/]*$","",1);
             seen[d]++;
             if ($NF ~ /\.tmp$|^(desktop\.ini|Thumbs\.db|\.picasa\.ini)$/) {
               found[d]++;
             };
           };
           END {for (d in seen) { if (seen[d] == found[d]) {print d}}}' 

Это использует findдля вывода списка файлов (и только файлов,-type f)завершающихся NUL -в целевом каталоге или ниже него (~/), и направляет их в сценарий awk. 2>/dev/nullпозволяет избавиться от предупреждающих сообщений из find, если/когда у пользователя нет разрешения спускаться в некоторые подкаталоги -.

Сценарий awk использует /в качестве разделителя полей и устанавливает для разделителей записей ввода (RS )и вывода (ORS )значение NUL. Он извлекает часть имени файла, относящуюся к каталогу, из входной записи и подсчитывает количество просмотров этого каталога (, используя ассоциативный массивseen). Затем, если конечное поле ($NF )совпадает с одним из желаемых шаблонов имени файла, он ведет подсчет совпадений (с использованием ассоциативного массиваfound).

Как только все вводные данные обработаны, он выводит каждый каталог, где количество просмотров каталога равно количеству найденных совпадений для этого каталога.

т. е. он печатает только каталоги, содержащие ТОЛЬКО совпадающие файлы.

Поскольку ORS имеет значение NUL, ее выходные данные можно безопасно использовать в качестве входных данных для xargs -0r rm -rfили аналогичной команды без риска возникновения проблем из-за пробелов, переводов строк или других проблемных метасимволов оболочки -в каталоге. имена.

Вывод может быть дополнительно обработан любым инструментом или языком сценариев, которые могут работать с вводом, разделенным NUL -, включая perlи версии GNU sed, sort, grep, head., tailи многие другие. Во многих случаях вам, вероятно, лучше либо настроить параметры find, либо выполнить дополнительную обработку в сценарии awk(, либо просто переписать все это в perlс помощью модуля File::Find).

Кстати, если вы еще не определились с тем, какую -обработку постов (если вообще )вы хотите выполнять в списке каталогов,перенаправление вывода find... | awk...в файл полезно, потому что операция findочень требовательна к дисковому вводу-выводу -использование файла в качестве входных данных для дальнейшей обработки позволяет избежать многократного запуска только для предоставления одного и того же ввода (т.е. это кэш ).

Наконец, если вы хотите визуально изучить вывод (, например. чтобы убедиться, что вы не собираетесь удалять что-либо важное ), измените строку RS=ORS="\0"на RS="\0", чтобы вы получили строку -между каждым именем каталога. Это нельзя безопасно использовать в качестве ввода для xargs, потому что строки -являются допустимыми символами в именах файлов/каталогов unix.

1
14.10.2021, 17:44
1 ответ

Программа Lua в основном сводится к запуску

io.popen("syntax(error) 2>&1 1>outputfile"):read("*all")

, который работает эквивалентно

sh -c 'syntax(error) 2>&1 1>outputfile'

io.popen()захватывает stdout запускаемой оболочки, но не stderr. Если бы там не было синтаксической ошибки, то перенаправления устраивали бы stderr в канал и stdout в файл. Но из-за синтаксической ошибки оболочка так далеко не заходит, перенаправления не обрабатываются. (Оболочка не понимает, что вы пытаетесь ей приказать.)

Чтобы на самом деле захватить как stdout, так и stderr, перед запуском внешней команды обычно подключают оба к каналам (или чему-то еще ). Например. Python subprocess.Popen()имеет аргументы stdoutи stderrдля этого. Но стандартная библиотека Lua немного беднее, и не похоже, что она доступна напрямую. Вам придется написать модуль C, чтобы обеспечить эту функцию.

Как упоминалось в комментариях, было бы полезно заключить команду в eval, так как результирующая командная строка будет иметь вид

eval 'syntax(error)' 2>&1 1>outputfile

, и оболочка будет обрабатывать перенаправления перед запуском eval. Но тогда, конечно, вам нужно добавить дополнительный набор экранирования, чтобы защитить любые одинарные кавычки, которые могут быть у вас во внутренней команде.

2
15.10.2021, 15:19

Теги

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