cp -a foo/* bar/
скопирует содержимое foo в bar, заменив все файлы, которые уже существуют. Я могу использовать флаг -n, чтобы cp
не перезаписывать существующие файлы или -i
чтобы он интерактивно спрашивал, перезаписывать ли файлы.
Вопросы
- Есть ли способ сделать так, чтобы файл завершился
cp
неудачей и возвращал код ошибки, если он уже существует? - Если нет, то можно ли обойтись без него
rsync
или каким-то другим распространенным инструментом?
решение1
Линукс
Если файл существует в Linux, возможна ошибка, если использовать небольшой хак с GNU nohup
. nohup
перенаправляет /dev/null
на stdin
, поэтому любые интерактивные запросы игнорируются, но рассматривает использование stdin
как ошибку.
$ nohup cp -ia foo/* bar/
Чтобы немного прибраться:
$ nohup cp -ia foo/* bar/ 2>nohup.out && rm nohup.out || cat nohup.out
- По умолчанию
nohup
перенаправляетstdout
наnohup.out
иstderr
наstdout
. 2>nohup.out
stderr
также помещает в файл.- Будет
&& rm || cat
выполнена очистка при успешном выполнении или вывод ошибкиnohup.out
при ошибке. Вы можете добавить любую обработку ошибок, которую хотите, вместо/включаяcat
или удалить все это и работать$?
как обычно. - Вам придется быть немного умнее в отношении расположения временных файлов, если вы используете это всерьез (
mktemp -d
)
БСД
В BSD вы можете перенаправить stdin
на , cp
который будет рассматриваться как n
и вернет статус, отличный от 0.
$ cp -ia foo/* bar/ </dev/null
OSX
На OSX cp
ведет себя, как ни странно, не так, как на BSD, и возвращает ненулевой статус при -n
пропущенном файле.
$ cp -n foo/* bar/