Как определить EOD

Я хотел бы прочитать различные разделы с ленты DDS с помощью сценария
На данный момент я использую следующий скрипт

TAPE=/dev/nst0         
BLOCK_SIZE=32768        
COUNTER=1
END_OF_DATA=120

while [  $COUNTER -lt $END_OF_DATA ] 
do      
       dd if=$TAPE bs=$BLOCK_SIZE of=file_$COUNTER  
       let COUNTER+=1 
done

Однако, как вы можете видеть, мой скрипт может читать максимум 120 разделов.

Как я могу изменить этот код, чтобы скрипт мог автоматически распознавать конец данных на ленте

Спасибо

2 ответа

Решение

Вы можете продолжать сравнивать отчет с размером блока. И да, вы должны открыть устройство только один раз и продолжить чтение с него.

TAPE=/dev/nst0 
BLOCK_SIZE=32768
COUNTER=1

while [ "$(dd bs="$BLOCK_SIZE" of="file_$COUNTER" 2>&1 count=1 | awk '/bytes/ { print $1 }')" -eq "$BLOCK_SIZE" ]; do
    let ++COUNTER
done < "$TAPE"

Скрипт тестируется с файлом.

Вы также можете удалить последний файл, если последнее число прочитанных байтов было всего 0:

while
    BYTES_READ=$(dd bs="$BLOCK_SIZE" of="file_$COUNTER" 2>&1 count=1 | awk '/bytes/ { print $1 }')
    [ "$BYTES_READ" -eq "$BLOCK_SIZE" ]
do
    let ++COUNTER
done < "$TAPE"

[ "$BYTES_READ" -eq 0 ] && rm -f "file_$COUNTER"

Если вы хотите отправить сообщение во время обработки ленты, вы можете использовать перенаправления и использовать для этого другой дескриптор файла:

TAPE=temp
BLOCK_SIZE=32768
COUNTER=1

while
    FILE="file_$COUNTER"
    echo "Reading $BLOCK_SIZE from $TAPE and writing it to file $FILE."
    BYTES_READ=$(dd bs="$BLOCK_SIZE" of="$FILE" count=1 2>&1 <&4 | awk '/bytes/ { print $1 }')
    echo "$BYTES_READ bytes read."
    [ "$BYTES_READ" -eq "$BLOCK_SIZE" ]
do
    let ++COUNTER
done 4< "$TAPE"

[ "$BYTES_READ" -eq 0 ] && rm -f "$FILE"

Пример вывода:

Reading 32768 from temp and writing it to file file_1.
32768 bytes read.
Reading 32768 from temp and writing it to file file_2.
32768 bytes read.
Reading 32768 from temp and writing it to file file_3.
32768 bytes read.
Reading 32768 from temp and writing it to file file_4.
32768 bytes read.
Reading 32768 from temp and writing it to file file_5.
32268 bytes read.

Другой вариант - просто отправить echoс /dev/stderr,

echo "Reading $BLOCK_SIZE from $TAPE and writing it to file $FILE." >&2

Чтобы сделать это немного быстрее, используйте exec внутри подоболочки, чтобы предотвратить лишнюю вилку:

BYTES_READ=$(exec dd ...)

Как я сказал в комментарии, я не очень разбираюсь в этом вопросе, но как ddостанавливается в конце каждого раздела ", почему бы вам просто не прочитать, пока нечего читать?

TAPE=/dev/nst0         
BLOCK_SIZE=32768        
COUNTER=1

while true 
do      
       dd if=$TAPE bs=$BLOCK_SIZE of=file_$COUNTER

       if [ \! -s file_$COUNTER ]
       then
               # clean-up empty file and exit the loop
               rm file_$COUNTER
               break
       fi
       let COUNTER+=1 
done

(непроверенные)

Другие вопросы по тегам