пытается CP каталог / dev / null

То, что я действительно пытаюсь сделать, это проверить, что данные на внешнем диске все еще читаемы. Я думал, что самый простой и надежный способ сделать это - скопировать все в /dev/null. Это прекрасно работает для файла. Но когда я добавляю -R к рекурсивному копированию структуру директории, если происходит сбой (предположительно), потому что он не может создавать подкаталоги в /dev/null.

Когда я пытаюсь:

cp -R Flintstones/ /dev/null

я получаю:

cp: cannot overwrite non-directory '/dev/null' with directory 'Flintstones/'

Но это работает:

cd Flintstones
cp Fred.txt /dev/null

Как мне скопировать весь каталог в один идти ??

Спасибо, и, пожалуйста, будьте нежны с новичком.

2
задан 28 October 2019 в 16:26

2 ответа

Привет и мог Спросить Ubuntu!

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

grep -r Zaphod Flintstones/

Вышеупомянутая команда означает это grep рекурсивно пройдет все файлы в Flintstones каталог ища строку "Zaphod" (Вы могли поместить некоторую другую строку там, она не имеет значения, просто что-то для grep для поиска, если Вы не хотите вывода, выбирают что-то, что Вы думаете, не произойдет ни в каком файле). Если команда завершается без сообщений об ошибках о нечитабельных файлах, то это означает, что каталог читаем.

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

1
ответ дан 2 December 2019 в 04:35

Использовать cat вместо cp

Вместо использования cp для чтения каждого файла можно использовать cat команда.

Экран ниже иллюстрирует catall.sh сценарий удара. Первый раздел показывает результаты для короткого промежутка времени (40 минут!) на /home/rick/. Второй раздел показывает в дисплее прогресса на /:

catall progress display.gif

В моей системе существует много разделов (включая две полных установки Windows 10), где все файлы читаются.

catall.sh сценарий удара

Со сценарием удара нужно назвать sudo полномочия, потому что существуют файлы в Linux обычный пользователь, не могут читать. Дополнительно необходимо передать параметр стартовому местоположению, чтобы начать читать файлы, например, / или /mnt/ext_drive, и т.д.:

#!/bin/bash

# NAME: catall.sh (cat every single file)
# PATH: $HOME/askubuntu/
# DESC: Answer for: https://askubuntu.com/questions/1184103/trying-to-cp-a-directory-to-dev-null/1184105#1184105
# DATE: October 27, 2019.

[[ $(id -u) != 0 ]] && { echo "Must be called with sudo" >&2 ; exit 2 ; }
[[ $1 != /* ]] && { echo "Parameter 1 must be a path" >&2 ; exit 3 ; }


DirCnt=0    # Directory count
FileCnt=0   # File
LinkCnt=0   # Symbolic Link
BdevCnt=0   # Block Device
CdevCnt=0   # Character Device
PipeCnt=0   # Pipe
SockCnt=0   # Socket
ZeroCnt=0   # Zero sized files count
SkipCnt=0   # Files skipped

updatedb    # Update locate's database for files added today
StartSec=$SECONDS

while read File ; do
    if [[ ! -e "$File" ]] ; then : # File no longer exists, stale database
    elif [[ -d "$File" ]] ; then (( DirCnt++ ))
    elif [[ -h "$File" ]] ; then (( LinkCnt++ ))
    elif [[ -b "$File" ]] ; then (( BdevCnt++ ))
    elif [[ -b "$File" ]] ; then (( CdevCnt++ ))
    elif [[ -c "$File" ]] ; then (( CdevCnt++ ))
    elif [[ -p "$File" ]] ; then (( PipeCnt++ ))
    elif [[ -S "$File" ]] ; then (( SockCnt++ ))
    # elif [[ $File == /mnt/* ]] ; then (( SkipCnt ++ ))
    elif [[ -s "$File" ]] ; then
        cat "$File" 1>/dev/null
        (( FileCnt++ ))
    else
        (( ZeroCnt++ ))
    fi
    printf "Number of Directories: %'d Files: %'d \r" "$DirCnt" "$FileCnt"
done <<<"$(locate "$1")"

echo # Line feed to keep statistics visible when job ends
printf "Number of Sybolic Links: %'d\n"     "$LinkCnt"
printf "Number of Block Devices: %'d\n"     "$BdevCnt"
printf "Number of Character Devices: %'d\n" "$CdevCnt"
printf "Number of Pipes: %'d\n"             "$PipeCnt"
printf "Number of Sockets: %'d\n"           "$SockCnt"
printf "Number of Zero sized files: %'d\n"  "$ZeroCnt"
# printf "Number of Skipped files: %'d\n"     "$SkipCnt"
echo
EndSec=$SECONDS
TotalSec=$(( EndSec - StartSec ))
printf "Total Seconds: %'d\n"               "$TotalSec"

Две строки комментируются для пропуска определенных каталогов:

    # elif [[ $File == /mnt/* ]] ; then (( SkipCnt ++ ))
# printf "Number of Skipped files: %'d\n"     "$SkipCnt"

Удалите тег комментария (#) и изменение /mnt/* к каталогу Вы хотите пропустить, чтобы сэкономить время. В моем случае /mnt/ представляет более чем миллион файлов в Windows и других установках Ubuntu на различных разделах.


Скорость cat ужасно

Конечные результаты были:

$ sudo ./catall.sh /

Number of Directories: 378,571 Files: 1,741,640 
Number of Sybolic Links: 92,011
Number of Block Devices: 25
Number of Character Devices: 55
Number of Pipes: 48
Number of Sockets: 138
Number of Zero sized files: 210,515

Total Seconds: 82,554

Процесс занял 23 часа или почти целый день!

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

$ time sudo dd if=/dev/nvme0n1p4 of=/dev/null bs=100M
3719+1 records in
3719+1 records out
389969573888 bytes (390 GB, 363 GiB) copied, 249.867 s, 1.6 GB/s

real    4m9.896s
user    0m0.017s
sys     2m38.305s

Почему использование sudo с catall.sh сценарий?

Этот пример иллюстрирует почему sudo требуется:

$ locate udev.log.1.gz
/mnt/clone/var/log/upstart/udev.log.1.gz
/var/log/upstart/udev.log.1.gz

$ cat /var/log/upstart/udev.log.1.gz | wc
cat: /var/log/upstart/udev.log.1.gz: Permission denied
      0       0       0

$ sudo cat /var/log/upstart/udev.log.1.gz | wc
      0       1      82
0
ответ дан 2 December 2019 в 04:35

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

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