Сценарий для контроля папки для новых файлов?

Как насчет того, чтобы использовать su команда?

$ whoami
user1
$ su - user2
Password:
$ whoami
user2
$ exit
logout

Если Вы хотите войти в систему как корень, нет никакой потребности указать имя пользователя:

$ whoami
user1
$ su -
Password:
$ whoami
root
$ exit
logout

Обычно можно использовать sudo для запуска новой оболочки как, пользователь, Вы хотите; -u флаг позволяет Вам указать имя пользователя, которое Вы хотите:

$ whoami
user1
$ sudo -u user2 zsh
$ whoami
user2

Существует больше окольных путей, если у Вас нет sudo доступа, как ssh username@localhost, но sudo является, вероятно, самым простым, при условии, что это установлено, и у Вас есть разрешение использовать его.

135
16.08.2018, 14:39
10 ответов

Необходимо рассмотреть использование inotifywait, как пример:

inotifywait -m /path -e create -e moved_to |
    while read path action file; do
        echo "The file '$file' appeared in directory '$path' via '$action'"
        # do something with the file
    done

В Ubuntu inotifywait обеспечивается inotify-tools пакет. С версии 3.13 (текущий в Ubuntu 12.04) inotifywait будет включать имя файла без-f опции. Более старые версии, возможно, должны быть принуждены. То, что важно для примечания, то, что -e опция к inotifywait лучший способ состоит в том, чтобы сделать фильтрацию событий. Кроме того, Ваш read команда может присвоить позиционный вывод в несколько переменных, которые можно принять решение использовать или проигнорировать. Нет никакой потребности использовать grep/sed/awk для предварительной обработки вывода.

163
27.01.2020, 19:29
  • 1
    Здорово! inotifywait был, что я хотел. –  ihatetoregister 19.11.2011, 20:50
  • 2
    Просто хочу обновить это. Вам не нужен awk для достижения этого. можно отфильтровать события с '-e, создают' и получают только имя файла путем выполнения '-f %f' или полный путь с помощью '-f %w%f'. Таким образом, первая строка вышеупомянутого сценария становится: inotifywait-m / соединяют-f каналом %w%f-e, создают | –  Lugoues 03.03.2013, 18:44
  • 3
    @Lugoues и теперь когда Вы пытаетесь использовать-f, Вы добираетесь The '--filename' option no longer exists. The option it enabled in earlier versions of inotifywait is now turned on by default. Так, только необходимо сделать inotifywait -m /path -e create | Я собираюсь попытаться отредактировать этот ответ. –  Bruno Bronosky 17.04.2014, 09:27
  • 4
    Теперь существует также портативный инструмент для него, звонил fswatch. Я не записал это, но это - открытый исходный код, и я использую его. –   30.07.2015, 16:22

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

Можно использовать следующую команду:

ls -1A isempty | wc -l

только, чтобы проверить, пуста ли папка все еще, на самом деле она возвратит 0, если нет никакого нового файла (следовательно isempty папка все еще пуста), или, с другой стороны, она возвратит значение, больше, чем 0 (на самом деле количество файлов в настоящее время в папке).

Это сказало, что глупое, если/затем тест может сделать остальную часть работы:

if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi

Конечно, do_something функция должна будет управлять файлом (файлами) в isempty папка и затем удаляет его (их) из самой папки после обработки.

Добавление строки как следующее в Вашем crontab осуществит проверку однажды минута и инициирует do_something действие, если папка не пуста, конечно:

* * * * *     if [ $(ls -1A isempty | wc -l) -gt 0 ] ; then do_something ; fi
9
27.01.2020, 19:29
  • 1
    Это решение работает на смонтированные удаленные файловые системы. разработчик (разработчики) inotify-инструментов работает над предохранителем (или был в середине 2014). –  Rondo 26.05.2015, 03:07
  • 2
    Вы никогда не должны использовать ls для сценариев. Использовать find или простой globbing вместо этого: mywiki.wooledge.org/ParsingLs –  andsens 29.11.2016, 01:05

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

То, что Вы ищете, называют inotify. Его встроенный в ядро Linux и можно в основном сидеть, там ожидая, что что-то произойдет, в котором точка inotify возвращается и говорит 'эй, существует новый файл, названный foobar'

Для выполнения, что Вы хотите, необходимо было бы переключиться на что-то как жемчуг и использовать Linux:: Inotify2 (Python, вероятно, поддерживает inotify также, но я - человек жемчуга).

2
27.01.2020, 19:29

Я предпочитаю incron, как его более легкое для управления. По существу это - сервис, который усиливает inotify и можно установить конфигурации для принятия мер на основе операций изменения файла.

Исключая:

<directory> <file change mask> <command or action>  options
/var/www/html IN_CREATE /root/scripts/backup.sh

Вы видите полный пример здесь: http://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/

27
27.01.2020, 19:29

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

while true
do
       touch  ./lastwatch
       sleep 10
       find /YOUR/WATCH/PATH -cnewer ./lastwatch -exec SOMECOMMAND {} \;
done

Если обработка файлов не занимает слишком много времени, вы не должны пропустить ни одного нового файла. Вы также можете сделать фоновый режим работы... Это не пуленепробиваемый способ, но он служит некоторым целям без внешних инструментов, таких как inotify.

25
27.01.2020, 19:29

Если вы хотите обнаружить новые файлы, затем обработать их и в конце удалить обработанные файлы, вы можете использовать systemd.path. Этот метод основан на inotify. Существует опция DirectoryNotEmpty, поэтому systemd может запускать ваш скрипт всегда, когда обнаружит в каталоге какие-либо файлы. Вы должны помнить, что это будет работать только в том случае, если вы можете удалить запущенные файлы, а скрипт оставит каталог пустым.

Сначала подготовьте файл mymonitor.service

[Unit]
Description=Start the script

[Service]
Type=oneshot
ExecStart=/path/to/your/script

Затем перейдите к файлу mymonitor.path для определения пути

[Unit]
Description= Triggers the service

[Path]
DirectoryNotEmpty=/path/to/monitor

[Install]
WantedBy=multi-user.target

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

Это основано на Monitoring File Access for Dummies

6
27.01.2020, 19:29

Это работает в cygwin и Linux. Некоторые из предыдущих решений, которые записывают файл, приводят к загрузке диска. У этого scipt нет такой проблемы:

SIG=1
SIG0=$SIG
while [ $SIG != 0 ] ; do
 while [ $SIG = $SIG0 ] ; do
   SIG=`ls -1 | md5sum | cut -c1-32`
   sleep 10
 done
 SIG0=$SIG
 ls -lrt | tail -n 1
done
0
27.01.2020, 19:29

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

Var_dir="${1:-/tmp}"
Var_diff_sleep="${2:-120}"
Var_diff_opts="--suppress-common-lines"
Func_parse_diff(){
    _added="$(grep -E '>' <<<"${@}")"
    if [ "${#_added}" != "0" ]; then
        mapfile -t _added_list <<<"${_added//> /}"
        _let _index=0
        until [ "${#_added_list[@]}" = "${_index}" ]; do
            _path_to_check="${Var_dir}/${_added_list[${_index}]}"
            if [ -f "${_path_to_check}" ]; then
                echo "# File: ${_path_to_check}"
            elif [ -d "${_path_to_check}" ]; then
                echo "# Directory: ${_path_to_check}"
            if [ -p "${_path_to_check}" ]; then
                echo "# Pipe: ${_path_to_check}"
            fi
            let _index++
        done
        unset _index
    fi
}
Func_watch_bulk_dir(){
    _current_listing=""
    while [ -d "${Var_dir}" ]; do
        _new_listing="$(ls "${Var_dir}")"
        _diff_listing="$(diff ${Var_dec_diff_opts} <(${Var_echo} "${_current_listing}") <(${Var_echo} "${_new_listing}"))"
        if [ "${_diff_listing}" != "0" ]; then
            Func_parse_diff "${_diff_listing}"
        fi
        _current_listing="${_new_listing}"
        sleep ${Var_diff_sleep}
    done
}

Вот ссылка на скрипт , который использует модифицированную версию выше для автоматического дешифрования файлов или каталогов, найденных в его точке монтирования sshfs; вышеупомянутый проект.

0
27.01.2020, 19:29

Если вы пришли сюда за простым, быстрым и удобным решением, прочитав заголовок, вы можете использовать watch

watch -n 0.1 ls <your_folder>

Отслеживает вашу папку и выводит список всего, что в ней, каждые 0,1 секунды

Недостаток

Нет -scriptable (варианты сценариев см. в других ответах)

Не в режиме реального времени, поэтому, если файл был создан и удален менее чем за 0,1 секунды, это не сработает, watchподдерживает только не менее 0,1 секунды.

48
27.01.2020, 19:29

См. также Watchman (, основанный на inotify ), особенно при комплексном мониторинге и запуске действия -. Он доступен не только для Linux, но также для Windows и Mac. Подробнее см. A :Watchman Q :Как отслеживать изменения всего дерева каталогов в Linux? .

0
28.09.2020, 17:44

Теги

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