Как проверить каждый файл в каталоге и попросить пользователя выполнить действие в csh shell

Ваш вопрос очень неясен, но из того, что я могу понять, вы пытаетесь периодически запускать что-то и хотите получить уведомление по электронной почте, когда что-то пойдет не так, верно?

Если это так, просто заставьте ваш shell-скрипт печатать сообщения об ошибках и запускайте его из cron; cron автоматически отправит вам электронное письмо, если скрипт выдаст какой-либо результат. Для получения дополнительной информации о том, как это сделать, запустите man crontab и man 5 crontab, и прочитайте эту документацию.

-1
20.03.2019, 14:56
1 ответ

Часть вашего шелл-кода выглядит как код bash, хотя вы используете строку #!-, указывающую csh. cshне имеет команды read, поэтому вы получаете ошибку signal 13.

Сигнал 13 — это сигнал PIPE, и он отправляется процессу, когда он пытается записать в мертвый канал (канал, который никто не читает с другого конца ). Канал мертв, потому что вызов readзавершился неудачно в цикле while-. Это не удалось, так как оно недоступно в csh.

Если бы уcshбыла команда read, ваш цикл получил бы имена файлов, но у вас не было бы никакого способа узнать, где эти имена файлов принадлежат (в каком подкаталоге )так как вы удалили из них путь к каталогу. Поэтому вы не сможете многого с ними сделать.


Самым самым простым способом сделать это было бы findзадать вопрос пользователю:

find. -type f -ok some-action '{}' ';'

Перед выполнением утилиты some-actionс именем пути в качестве аргумента будет запрашиваться подтверждение для каждого имени пути. Он запросит полную командную строку, которая будет выполняться для данного имени пути, так что это не совсем то, что вы могли иметь в виду.

Заметьте также, что при указании -type fбудут найдены все обычные файлы, в то время как ваш -name '*'тест будет всегда верен для всех типов файлов, включая каталоги. Я также использую.(текущий каталог )для каталога верхнего уровня -для find, что вы, кажется, хотите сделать с вашей переменной DIR.

Чтобы вручную запрашивать у пользователя ввод для каждого файла и в то же время правильно обрабатывать пути, проще всего сделать что-то вроде

find. -type f -exec sh -c '
    for pathname do
        printf "process %s (%s)?\n" "${pathname##*/}" "$pathname" >&2
        read answer
        case $answer in [Nn]*) continue; esac

        printf "processing %s...\n" "$pathname" >&2
        # process "$pathname" here
    done' sh {} +

Это предполагаетsh-подобную оболочку и будет порождать sh -cдля пакетов путей, найденных с помощью find. Сценарий внутренней оболочки спрашивал пользователя, хотят ли они обрабатывать каждый отдельный путь или нет.Если пользователь ответит словом, начинающимся сn(без учета регистра ), будет рассмотрен следующий путь.

Бит "${pathname##*/}"в коде эквивалентен "$( basename "$pathname" )", поскольку он удаляет все в $pathnameдо последней косой черты включительно.

Команда findдействует как своего рода генератор имен путей для циклаfor-во внутреннем скрипте, поэтому передача путей или имен файлов в циклwhile-никогда не требуется.

Связанные:

5
28.01.2020, 05:06

Теги

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