Как выполнить cp файл только в том случае, если он не существует, иначе выведите ошибку?

aws s3 cp "dist/myfile" "s3://my-bucket/production/myfile"

Он всегда копирует myfile в s3 - я хотел бы копировать файл ТОЛЬКО, если он не существует, иначе проведите ошибку. Как я могу это сделать? Или, по крайней мере, как я могу использовать awscli для проверки наличия файла?

Ответ 1

Вы можете проверить наличие файла, перечислив файл и посмотрев, возвращает ли он что-либо. Например:

aws s3 ls s3://bucket/file.txt | wc -l

Это вернет ноль (без строк), если файл не существует.


Если вы хотите скопировать файл только в том случае, если он не существует, попробуйте команду sync command, например:

aws s3 sync . s3://bucket/ --exclude '*' --include 'file.txt'

Это синхронизирует локальный файл с удаленным объектом, копируя его, только если он не существует или если локальный файл отличается от удаленного объекта.

Ответ 2

Итак, получается, что "aws s3 sync" не выполняет файлы, а только каталоги. Если вы дадите ему файл, вы получите... интересное... поведение, так как оно обрабатывает все, что вы даете ему, как каталог, и бросает на него черту. По крайней мере, aws-cli/1.6.7 Python/2.7.5 Darwin/13.4.0 делает.

    %% date > test.txt
    %% aws s3 sync test.txt s3://bucket/test.txt
    warning: Skipping file /Users/draistrick/aws/test.txt/. File does not exist.

Итак, если вы - только хотите синхронизировать файл (только загрузить, если существует, и если контрольная сумма соответствует), вы можете сделать это:

    file="test.txt"
    aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"

Обратите внимание на порядок исключения/включения - если вы отмените это, оно не будет содержать ничего. И ваш источник и включить путь должны иметь здравомыслие вокруг их соответствия, так что возможно $(basename $file) для того, чтобы --include, если вы используете полные пути... aws --debug s3 sync - ваш друг здесь чтобы посмотреть, как оцениваются оценки.

И не забывайте, что целью является ключ каталога, а не ключ файла.

Вот рабочий пример:

  %% file="test.txt"
  %% date >> $file
  %% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
  upload: ./test.txt to s3://bucket/test.txt/test.txt
  %% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
  %% date >> $file
  %% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
  upload: ./test.txt to s3://bucket/test.txt/test.txt

(теперь, если бы только был способ попросить aws s3 -just- проверить контрольную сумму, поскольку, похоже, всегда выполняются контрольные суммы многострочного стиля.. о, может быть, некоторые --dryrun и некоторые выходы и синхронизация вывода. )

Ответ 3

Вы можете сделать это путем перечисления и копирования в том и только в том случае, если список удался.

aws s3 ls "s3://my-bucket/production/myfile" || aws s3 cp "dist/myfile" "s3://my-bucket/production/myfile"

Изменить: заменить && & к || чтобы иметь желаемый эффект, если список не работает, скопируйте

Ответ 4

  AWS HACK

Вы можете запустить следующую команду, чтобы вызвать ERROR, если файл уже существует

  • Запустите команду aws s3 sync, чтобы синхронизировать файл с s3, он вернет скопированный путь, если файл не существует, или выдаст пустой вывод, если он выйдет
  • Запустите команду wc -c, чтобы проверить количество символов и выдать ошибку, если выходной сигнал равен нулю

com=$(aws s3 sync dist/s3://my-bucket/production/| wc -c);if [[ $com -ne 0 ]]; then exit 1; else exit 0; fi;

ИЛИ

#!/usr/bin/env bash
com=$(aws s3 sync dist s3://my-bucket/production/ | wc -c)
echo "hello $com"
if [[ $com -ne 0 ]]; then
echo "File already exists"
exit 1
else
echo "success"
exit 0
fi