使用s3cmd并行上传至同一S3桶目录后index.js损坏,求原因
index.js Got Corrupted After Running This Script Let's break down the likely reasons and fix them step by step:
Possible Causes of Corruption
1. Parallel Upload Conflict
You're running two s3cmd processes in parallel (the & at the end of the first s3cmd line sends it to the background). The first command explicitly excludes index.js, but the second truncated command appears to upload the full directory—including index.js.
When two processes try to upload the same file to the exact same S3 path at the same time, race conditions occur:
- One upload might overwrite the other mid-process, leaving a partial or mixed file on S3.
- Even though S3's PUT operations are atomic, if one process fails mid-upload while the other completes, you could end up with a corrupted file that mixes incomplete and complete data.
2. Incomplete Gzip/Move Operation
Before the uploads, you run:
gzip dist/production/index.js mv dist/production/index.js.gz dist/production/index.js
If gzip fails silently (e.g., permission issues, missing original index.js), the mv command would try to move a non-existent index.js.gz file. This would either fail entirely or leave you with an empty/corrupted index.js that gets uploaded.
3. Truncated Second s3cmd Command
Your second s3cmd line cuts off at --acl-public ...—if this command has invalid flags or missing arguments, it might behave unpredictably, potentially causing partial or incorrect uploads of index.js.
Fixes to Prevent Corruption
1. Avoid Parallel Uploads for the Same File
Instead of running s3cmd processes in parallel, execute them sequentially. If you need to split the upload (exclude index.js first, then upload it separately), remove the & and run them one after another:
# Upload everything except index.js first s3cmd --access_key="$S3_ACCESS_KEY" --secret_key="$S3_SECRET_KEY" \ --acl-public --no-mime-magic --progress --recursive \ --exclude "dist/production/index.js" \ put dist/production/ "s3://${BUCKET}/something/${BUILD_IDENTIFIER}/production/" # Now upload only index.js s3cmd --access_key="$S3_ACCESS_KEY" --secret_key="$S3_SECRET_KEY" \ --acl-public --no-mime-magic --progress \ put dist/production/index.js "s3://${BUCKET}/something/${BUILD_IDENTIFIER}/production/index.js"
2. Add Error Checking to Gzip/Move
Ensure the compression and renaming steps succeed before proceeding to uploads:
# Gzip the file, exit if it fails gzip dist/production/index.js || { echo "Error: Failed to gzip index.js"; exit 1; } # Move the compressed file, exit if it fails mv dist/production/index.js.gz dist/production/index.js || { echo "Error: Failed to rename gzipped file"; exit 1; }
3. Use a Single s3cmd Command (If Possible)
Unless you have a specific reason to split the upload, handle everything in one command—no parallel execution needed:
s3cmd --access_key="$S3_ACCESS_KEY" --secret_key="$S3_SECRET_KEY" \ --acl-public --no-mime-magic --progress --recursive \ put dist/production/ "s3://${BUCKET}/something/${BUILD_IDENTIFIER}/production/"
4. Verify File Integrity Post-Upload
After uploading, download the index.js from S3 and test if it can be decompressed properly:
# Download the file s3cmd get "s3://${BUCKET}/something/${BUILD_IDENTIFIER}/production/index.js" test-index.js # Test decompression gzip -d test-index.js if [ -f test-index.js ]; then echo "File is valid and decompressed successfully" rm test-index.js else echo "Error: Downloaded file is corrupted" fi
内容的提问来源于stack exchange,提问作者Vitali Zaidman

