Когда я использую эту команду ls repo/* | xargs -I {} cp {} backup_repo/
, я получаю ошибку -bash: /usr/bin/ls: Argument list too long
. Я понимаю, что причина этого в том, что bash фактически расширяет звездочку до каждого соответствующего файла, создавая очень длинную командную строку. Как исправить эту ошибку?
решение1
Используйте xargs --show-limits </dev/null
для просмотра текущих лимитов.
Лучший способ:
find repo -maxdepth 1 -type f -name '*' -print0 | \
xargs -0 --no-run-if-empty \
cp --target-directory=./backup_repro/
Плохая идея — размещать каталог резервного копирования в том же каталоге, что и файлы, которые вы копируете. Это может привести к резервному копированию резервной копии, содержащей резервную копию, содержащую ..., а размер резервной копии стремится к бесконечности.
Читать man find xargs cp
.
решение2
Если вы просто хотите сделать копию repo
в backup_repo
, используйте rsync
:
rsync -a repo/ backup_repo
Или, если вам нужна только резервная копия, создайте tar
архив,
tar -c -f repo.tar repo
Если вы хотите скопировать только видимые имена, которые *
раскрываются внутри repo
, и пропустить все скрытые имена (например .git
), то вы, возможно, можете использовать
printf '%s\0' repo/* | xargs -0 -I {} cp -R -- {} backup_repo
или, предположим, GNU cp
,
printf '%s\0' repo/* | xargs -0 cp -t backup_repo -R --
Утилита printf
встроена в bash
оболочку и поэтому не будет иметь тех же ограничений на размер списка аргументов, как внешняя утилита ls
.