Использование cp для копирования файлов из каталога, в котором также есть пустой каталог, приводит к возврату значения ошибки, что приводит к сбою моего скрипта.
Есть ли способ просто пропускать каталоги без возвращаемого значения ошибки? Я бы хотел, чтобы значение ошибки отражало любые ошибки, но наличие пустого каталога должно просто пропускаться, без сообщения об ошибке.
Я мог бы просто добавить рекурсивный флаг -r
, но что делать, если я просто не хочу, чтобы каталог копировался, но яделатьхотите, чтобы сообщалось о любых ошибках?
решение1
Я предлагаю вам использовать rsync вместо cp, если это возможно, у него есть опция -m, которая исключит пустые папки, например:
rsync -am <origin> <destination>
Объяснение команды вExplainshell.com
Я использую опцию -a, потому что она выполняет множество полезных действий по умолчанию, но при желании вы также можете использовать опцию -r, которая установит только рекурсивный режим.
[Добавить комментарий]
Я не знаю способа сделать это с помощью cp, по крайней мере, на странице man не показано ни одной опции, которая сделает это за вас. Вы, вероятно, можете сделать более сложное решение, используя команду find
для поиска списка файлов/каталогов для копирования, а затем передать его в cp, но это будет намного сложнее, чем rsync. rsync даже довольно стандартен во многих Linux
решение2
cp
действительно не имеет возможности получить только файлы, но какберсерксказал, вы можете использовать find
вместе с cp
. На самом деле, это действительно просто:
# Copy only files
find /path/to/file -type f -execdir cp "{}" /dest/path ";"
Или:
# Copy everything except directories
find /path/to/file -not -type d -execdir cp "{}" /dest/path ";"
Объяснение
find
— это инструмент, который будет искать нужные вам файлы. В первом варианте мы устанавливаем -type f
возврат только обычных файлов. Во втором варианте мы устанавливаем возврат -not -type d
всего, кроме каталогов. find
выполняет переданные аргументы для -execdir
замены {}
одной записью результата за раз и останавливает команду, когда ;
она найдена ( ;
должна быть экранирована \;
или ";"
, иначе оболочка может раскрыть ее).
-execdir
запустит команду, указав папку файла в качестве «рабочего каталога», и это предпочтительнее, чем -exec
, проверьте ниже.
Документация -type
по опции:
-тип с
Файл имеет тип c:
б: блок (буферизованный) специальный
c: символ (небуферизованный) специальный
d: каталог
p: именованный канал (FIFO)
f: обычный файл
l: символическая ссылка; это никогда не бывает правдой, если действует опция -L или -follow, если только символическая ссылка не нарушена. Если вы хотите искать символические ссылки, когда действует -L, используйте -xtype.
с: гнездо
D: дверь (Солярис)
Документация -not
по опции:
!выражение
True, если expr ложно. Этот символ также обычно нуждается в защите от интерпретации оболочкой.
-нетвыражение
То же, что и ! expr, но не совместимо с POSIX.
Документация -execdir
по опции:
-execкоманда ;
Выполнятькоманда;true, если возвращается статус 0. Все последующие аргументы для find считаются аргументами команды, пока не встретится аргумент, состоящий из ';'. Строка '{}' заменяется текущим именем обрабатываемого файла везде, где она встречается в аргументах команды [...]. Обе эти конструкции, возможно, придется экранировать (с помощью '\') или заключить в кавычки, чтобы защитить их от расширения оболочкой. Указанная команда выполняется один раз для каждого соответствующего файла. Команда выполняется в начальном каталоге.Использование действия -exec сопряжено с неизбежными проблемами безопасности; вместо этого следует использовать опцию -execdir.
-execdirкоманда ;
Как и -exec, но указанныйкоманда запускается из подкаталога, содержащего соответствующий файл, который обычно не является каталогом, в котором вы начали find. Это гораздо более безопасный метод вызова команд, поскольку он позволяет избежать состояний гонки во время разрешения путей к соответствующим файлам. [...] Если вы используете эту опцию, вы должны убедиться, что ваша переменная окружения $PATH не ссылается на '.'; в противном случае злоумышленник может выполнить любые команды, которые ему нравятся, оставив соответствующим образом названный файл в каталоге, в котором вы запустите -execdir. То же самое относится к наличию записей в $PATH, которые являются пустыми или не являются абсолютными именами каталогов.