Проблема с копированием [использование cp]

Используя bash, вы можете использовать регулярное выражение для проверки числа:

#! /bin/bash
while [ -z "$REPLY" ]; do
    read -p "Enter a valid number: "
    if ! [[ "$REPLY" =~ ^[0-9]+$ ]] ; then
        echo Bad number: $REPLY
        REPLY=
    fi
done
echo A valid number: $REPLY

Программа продолжает считывать ввод до тех пор, пока переменная $REPLYне будет установлена ​​с помощью read. Когда число совпадает с ^[0-9]+$, цикл завершается.

5
10.02.2019, 22:07
2 ответа

Шаблон /mnt/1804iso/.*расширяется, помимо прочего, до элемента каталога /mnt/1804iso/.., который совпадает с /mnt. Я предполагаю, что именно поэтому он начал копировать /mnt/data.

В этом случае я бы просто использовалrsync:

rsync -ai /mnt/1804iso/ /media/benny/0EB4-95E2

Это скопирует все /mnt/1804iso, включая скрытые файлы, в /media/benny/0EB4-95E2. Если оставить /в конце исходного каталога, будет создан каталог 1804isoниже целевого каталога.

В качестве альтернативы,включите параметр оболочки dotglobв bashс shopt -s dotglob, чтобы *соответствовал скрытым именам, а также не -скрытым именам (, но не .или..). Затем используйте

cp -Rn /mnt/1804iso/* /media/benny/0EB4-95E2/
3
27.01.2020, 20:33

.* расширится до вашего скрытого файла, .и ... Это неудачная часть того, как работает Bash расширение имени файла :есть запись в каталоге с именем .., которая состоит из начального .и любого количества символов после него, поэтому оно соответствует по .*и вкл.

Вы можете увидеть, как это происходит, запустив, например,.:

echo /mnt/1804iso/.*

, в котором будут перечислены /mnt/1804iso/.и /mnt/1804iso/..вместе с остальными.

../data— ваш каталог data. Вы получите структуру каталогов в месте назначения, подобную этой:

.hidden
xyz
data/
data/...
1804iso/.hidden
1804iso/xyz
...

То есть вы фактически получите две копии всего, что вы хотели скопировать, плюс все то, что вы не сделали. Если вы используете cp -Rnv, вы увидите, что он копирует и куда по ходу дела.

Некоторые другие оболочки подходят к этому лучше. В zsh это было бы ближе к тому, что вы хотите:только скрытый файл был бы скопирован. В Bash вы можете использовать от cp src/.[^.]* destдо почти , чтобы соответствовать поведению zsh, и перечислить два исходных местоположения. Кроме того, вы можете запустить shopt -s dotglobзаранее , а затем src/*расширится до включить точечные файлы, но исключить .и ..записи (, но это может привести к тому, что вы сделаете то, что вы не хотели делать позже, так что будьте осторожны ).


Вместо того, что вы действительно хотели сделать, я предлагаю использовать rsync :

rsync -avx /mnt/1804iso/ /media/benny/0EB4-95E2/

Будет скопировано содержимое каталога 1804isoв место назначения (обратите внимание на последнюю косую черту! ), включая все скрытые файлы.

9
27.01.2020, 20:33

Теги

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