cp только файлы, пропуская каталоги

cp только файлы, пропуская каталоги

Использование 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, которые являются пустыми или не являются абсолютными именами каталогов.

https://linux.die.net/man/1/find

Связанный контент