Intereting Posts
Каковы последствия отсутствия действительной таблицы разделов? GPT или MBR: Откуда я знаю? Собрать все данные sar Лучший способ продолжить остановку перемещения (mv) путем слияния каталогов? как выполнять команды на удаленном сервере как разные пользователи Предотвратите добавление стандартного маршрута eth0 Основной вопрос: Почему linux-образ не соответствует установленной версии? Разделение большого дерева каталогов по типу файла Как повернуть микрофонный разъем в гнездо для наушников? Как скопировать текст из командной строки в буфер обмена без использования мыши? Включить анонимную привязку в openldap Как превратить файл tar в файл tgz? Захват timestamped событий мыши X и рендеринг видео с пользовательским указателем мыши? Ubuntu 16.04 останавливает загрузку, у него настроено шифрование LVM и LUKS, восстановление суперблока уже выполнено Если вы ^ Z из процесса, он становится «остановлен». Как вы снова включаетесь?

Проверка наличия файлов против списка

У меня есть «командный» текстовый файл, который выдает команду загрузки файла данных в каждой строке. Я посылаю командный файл в bash. Однако небольшой процент загрузок не работает. Вот алгоритм, который я использую, чтобы узнать, чего не хватает:

  1. После загрузки я возвращаюсь через командный файл и проверяю, существует ли каждый файл загрузки.
  2. Если загрузка не существует, я копирую командную строку в новый командный файл.
  3. Я остаюсь с новым командным файлом для оставшихся загрузок.

Вот сценарий bash, который я реализовал с помощью:

1 #!/bin/bash 2 while read line 3 do 4 for item in $line 5 do 6 if [[ $item == *out_fname* ]]; then 7 splitline=(${item//=/ }) 8 target_file=${splitline[1]} 9 if [ ! -f $target_file ]; then 10 echo $line >> stillneed.txt 11 fi 12 fi 13 done 14 done < "$@" 

Вопрос: Это хорошо работает, но есть ли лучший алгоритм или реализация (возможно, использование чего-то другого, кроме bash)? То, что я сделал, это просто сделать то, что человек должен делать. Но похоже, что Unix всегда имеет лучший способ делать что-то …

Похоже, вы ищете 'out_fname =', а не только 'out_fname'.

Я либо сделаю это в сочетании awk и shell, либо в python. В awk / shell:

 awk '{for(i=0;i<NF;i++) {if (index($i, 'out_fname=')) {split($i,A,/=/);print A[i]}}' "$@" | while read filename; do if [ ! -f $filename ]; then echo $filename; fi done > stillneed.txt 

В python:

 import fileinput, os stillneed = open("stillneed.txt", "w") for line in fileinput.input(): for filename in [l.split('=')[1] for l in line.split() if l.find('out_fname=')!=-1]: if not os.path.exists(filename): print >>stillneed, filename 

не уверен, что это поможет, но у меня есть функция повторить команды, пока они не вернут успех:

 retry () { local delay=1 n if ! [[ $1 = *[^0-9]* ]]; then # TODO allow delay=0 (prevents Ctrl-C) if (($1 > 0)); then delay=${1:1} fi shift fi # run command while ! "$@"; do echo "retrying in ${delay}s" for ((n=delay; n>0; n--)); do sleep 1 || return done done }; export -f retry 

Вместо того, чтобы проверить, что отсутствует после завершения первоначального сценария загрузки, рассмотрите возможность добавления некоторых проверок к указанному сценарию загрузки. Я не тестировал следующее, я просто написал это с головы:

 cat files_to_download|while read file; do SUCCESS="False" while [[ $SUCCESS == "False" ]]; do wget $file; if [[ $? -eq 0 ]]; then SUCCESS="True" fi done done 

Я бы рекомендовал echo копию строки при неудачной загрузке, вместо того, чтобы анализировать имена файлов, анализируя каждую строку в файле:

 [[ -f $1 ]] || { echo "$1 not found" >&2; exit 1; } while read -r line; do $line || echo "$line" >> stillneed done < "$1" 

Это будет более эффективным, а также означает, что вам не нужно беспокоиться о каких-либо нечетных именах файлов в будущем (например, с пробелами).

Если вы хотите улучшить существующий метод, вы можете использовать стандартное расширение параметра:

 for f; do while read -r line; do for item in $line; do [[ $item = out_fname=* ]] || continue [[ -f ${item#out_fname=} ]] || echo "$line" break # assuming one fname per line done done < "$f" done > stillneed 

.. но подумайте, что происходит с: out_fname='foo bar.ext' . Кроме того, имейте в виду, что это проверяет каждую строку после события, когда мы могли просто проверить, работала ли команда в то время, когда мы ее запускали.

Открытие по- stillneed однократно для всей петли более эффективно; Я не делал этого в первом фрагменте, так как мы, скорее всего, хотим видеть вывод из команд загрузки. Здесь есть только тесты, никаких внешних команд, поэтому имеет смысл открыть файл один раз. (Note using > будет обрезать файл в начале, я использовал for f чтобы разрешить несколько входных файлов в качестве позиционных параметров: добавление же самого выше должно быть легким, если вам это нужно.)

Единственное, что я должен подчеркнуть, это цитата: echo "$line" сильно отличается от echo $line . В общем, цитируйте все расширения параметров (включая переменные), если вы точно не знаете, что вы хотите разбить поле.