Вложенные циклы, если условия и фоновые задания в ударе

Если вы все равно хотите перезаписать данные зашифрованного диска незашифрованными данными (т.е. вас не волнует текущее содержимое), вам не нужно сначала разблокировать диск/раздел.

Если раздел имеет особый необычный тип раздела, вы можете захотеть изменить его, но в этом нет необходимости. Вы можете просто использовать mkfs.ext4 (или любой другой тип файловой системы) на разделе, который содержит раздел шифрования LUKS.

0
05.08.2014, 20:42
2 ответа

Благодаря советам @Ueless и @Orion, теперь я избил функцию до подчинения. Теперь она порождает все извлечения в фоновом режиме, больше не удаляет исходные файлы, и более чем на 25% быстрее для меня, чем ее предшественник. @Жиль отметил, что распараллеливание не для всех, так как это довольно дорогое хранение. Хотя для меня это было лучше, и если вы обнаружите, что вы можете использовать этот скрипт, я предоставлю его ниже:

extract () { # Extracts all archives and any nested archives of specified directory into a new child directory named after the archive.
IFS=$'\n'
trap "rm $skipfiles ; exit" SIGINT SIGTERM
shopt -s nocasematch # Allows case-insensitive regex matching
echo -e "\n=====Extracting files====="
skipfiles=`mktemp` ; echo -e '\e' > $skipfiles # This creates a temp file to keep track of files that are already processed. Because of how it is read by grep, it needs an initial search string to omit from the found files. I opted for a literal escape character because who would name a file with that?
while [ "`find "$1/" -type f -regextype posix-egrep -iregex '^.*\.(tar\.gz|tar\.bz2|tar\.xz|tar|tbz|tgz|zip|rar|7z)$' | grep -ivf $skipfiles | wc -l`" -gt 0 ]; do #The while loop ensures that nested archives will be extracted. Its find operation needs to be separate from the find for the for loop below because it will change.
    for z in `find "$1/" -type f -regextype posix-egrep -iregex '^.*\.(tar\.gz|tar\.bz2|tar\.xz|tar|tbz|tgz|zip|rar|7z)$' | grep -ivf $skipfiles`; do
        destdir=`echo "$z" | sed -r 's/\.(tar\.gz|tar\.bz2|tar\.xz|tar|tbz|tgz|zip|rar|7z)$//'` # This removes the extension from the source filename so we can extract the files to a new directory named after the archive.
        if [ ! -d "$destdir" ]; then
            echo "Extracting `basename $z` into `basename $destdir` ..."
            mkdir -p "$destdir"
            if [[ "$z" =~ ^.*\.7z$ ]]; then 7z x "$z" -o"$destdir" > /dev/null & 
            elif [[ "$z" =~ ^.*\.rar$ ]]; then unrar x -y -o+ "$z" "$destdir" &
            elif [[ "$z" =~ ^.*\.zip$ ]]; then unzip -uoLq "$z" -d "$destdir" 2>/dev/null &
            elif [[ "$z" =~ ^.*\.(tar\.gz|tar\.bz2|tar\.xz|tar|tbz|tgz)$ ]] ; then tar -xaf "$z" -C "$destdir" &
            fi
            echo `basename "$z"` >> $skipfiles # This adds the name of the extracted file to the omission list for the next pass.
        else echo "Omitting `basename $z`, directory with that name already exists."; echo `basename "$z"` >> $skipfiles # Same as last line
        fi
    done
    wait # This will wait for all files in this pass to finish extracting before the next one.
done
rm "$skipfiles" # Removes temporary file
}
1
28.01.2020, 02:28

Почему вы запускаете одну и ту же команду поиска несколько раз, дважды для каждого расширения? Можно просто сгенерировать одну единственную команду поиска, которая пройдет через дерево каталогов только один раз:

EXT_REGEX='.*(zip|rar|tar.gz|tar.bz2|tbz|tgz|7z|tar)$'
find . -regextype posix-egrep -iregex $EXT_REGEX

Теперь вам вообще не нужны вложенные циклы, и уж точно не нужна while, которая вызвала у вас проблему бесконечного цикла.

Во-вторых, ваш код сломан для имен файлов с пробелами в них. Это можно исправить, добавив

IFS=''

(чтобы остановить для z в ... разбиение вывода на пробелы).

Наконец, если вы прикрепите и в конце каждой из ваших if/elif ветвей, они будут работать параллельно.

BTW, что все эхо "$z" | rev должно выполнить? Вы каким-то образом получили многострочные имена файлов?

.
2
28.01.2020, 02:28

Теги

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