Вы можете использовать команду inotifywait
из inotify-tools в сценарии для создания жестких ссылок на созданные файлы в / tmp / some_folder
. Например, жестко связать все созданные файлы из / tmp / some_folder
в / tmp / some_folder_bak
:
#!/bin/sh
ORIG_DIR=/tmp/some_folder
CLONE_DIR=/tmp/some_folder_bak
mkdir -p $CLONE_DIR
inotifywait -mr --format='%w%f' -e create $ORIG_DIR | while read file; do
echo $file
DIR=`dirname "$file"`
mkdir -p "${CLONE_DIR}/${DIR#$ORIG_DIR/}"
cp -rl "$file" "${CLONE_DIR}/${file#$ORIG_DIR/}"
done
Поскольку это жесткие ссылки, они должны обновляться, когда программа их изменяет, но не удаляются, когда программа их удаляет. Вы можете удалить жестко связанные клоны обычным образом.
Обратите внимание, что этот подход далеко не атомарный, поэтому вы полагаетесь на этот сценарий для создания жестких ссылок, прежде чем программа сможет удалить вновь созданный файл.
Если вы хотите клонировать все изменения в / tmp
, вы можете использовать более распределенную версию скрипта:
#!/bin/sh
TMP_DIR=/tmp
CLONE_DIR=/tmp/clone
mkdir -p $CLONE_DIR
wait_dir() {
inotifywait -mr --format='%w%f' -e create "$1" 2>/dev/null | while read file; do
echo $file
DIR=`dirname "$file"`
mkdir -p "${CLONE_DIR}/${DIR#$TMP_DIR/}"
cp -rl "$file" "${CLONE_DIR}/${file#$TMP_DIR/}"
done
}
trap "trap - TERM && kill -- -$$" INT TERM EXIT
inotifywait -m --format='%w%f' -e create "$TMP_DIR" | while read file; do
if ! [ -d "$file" ]; then
continue
fi
echo "setting up wait for $file"
wait_dir "$file" &
done
Ваш цикл запускает бесконечное количество оболочек, но одну за другой, а не параллельно. При первом запуске цикла запускается bash
, который запускает новую оболочку и отображает приглашение. Родительская оболочка ожидает выхода этой оболочки; это происходит, когда вы набираете exit
, выходя из дочерней оболочки и возвращаясь к родительской оболочке, которая снова проходит цикл и запускает bash
, который запускает новую оболочку и отображает приглашение. ..
Вы можете отобразить свой уровень оболочки, запустив
echo $SHLVL
Вы увидите, что это число не меняется при последовательном вводе команд exit
.
Ваш цикл запускает один сеанс интерактивной оболочки на каждой итерации.
Интерактивный сеанс дает вам подсказку (поскольку он интерактивный). Выход из него возвращает управление циклу, который запускает другую интерактивную оболочку.
Вот почему вы не получаете огромное количество процессов bash
одновременно, только два, родительский, который запускает цикл, и дочерний, который дает вам новое приглашение.
Цикл также может быть записан.
while true; do bash; done
Утилита true
не принимает аргумент, она просто возвращает нулевое значение выхода, которое интерпретируется оболочкой как «истина».
Если вам нужен взрыв процессов bash
(так называемая «форк-бомба»), вы можете написать
while true; do { bash & }; done
Это запустит интерактивный сеанс bash
в каждой итерации цикла, а как фоновые процессы.Поскольку сеансы запускаются как фоновые процессы, цикл не будет ждать завершения последнего процесса bash
перед запуском следующего.
Возможно, вам придется перезагрузить систему, чтобы восстановиться.
Эта форк-бомба более безвредна, чем могла бы быть, поскольку она запускает только один новый процесс на каждой итерации. Другие вполне могут запускать процессы экспоненциально.