如何拆分Shell脚本为可通过命令行参数调用/跳过的函数?
Great question! Breaking down large scripts into modular functions is a smart move—it makes your code easier to read, maintain, and reuse. Let's walk through exactly how to wrap your three code segments into functions and add command-line arguments to control which steps run or get skipped.
Step 1: Wrap Each Code Segment into a Function
First, we'll turn each of your three tasks into a named function. This isolates the logic and makes it easy to call (or skip) later.
#!/bin/bash # Enable strict mode to catch errors early (good practice for beginners!) set -euo pipefail # Function 1: Install dependencies install_deps() { echo "🔧 Installing Python dependencies..." pip install -r ./docker/requirements.txt } # Function 2: Create Spark zip package create_zip() { echo "📦 Creating Spark zip archive..." ZIP_FILE="spark.zip" # Use quotes around variables to handle spaces (important!) zip -r "$ZIP_FILE" file.py # Export the ZIP_FILE variable so the upload function can use it export ZIP_FILE } # Function 3: Upload zip to S3 upload_to_s3() { echo "☁️ Uploading zip to S3..." # Check if S3_BUCKET_PATH is set (prevent errors) if [[ -z "${S3_BUCKET_PATH:-}" ]]; then echo "❌ Error: S3_BUCKET_PATH environment variable is not set!" exit 1 fi aws s3 cp "$ZIP_FILE" "${S3_BUCKET_PATH}/lib/" }
Step 2: Add Command-Line Argument Parsing
Next, we'll add logic to parse command-line flags that let you skip specific steps. We'll use simple --skip-* flags since they're intuitive for beginners.
Add this code after the functions:
# Initialize skip flags (default to false) SKIP_INSTALL=false SKIP_ZIP=false SKIP_UPLOAD=false # Parse command-line arguments while [[ $# -gt 0 ]]; do case "$1" in --skip-install) SKIP_INSTALL=true shift # Move to next argument ;; --skip-zip) SKIP_ZIP=true shift ;; --skip-upload) SKIP_UPLOAD=true shift ;; *) echo "❌ Unknown option: $1" echo "Valid options: --skip-install, --skip-zip, --skip-upload" exit 1 ;; esac done
Step 3: Execute Functions Based on Flags
Finally, we'll run each function unless the corresponding skip flag is set:
# Run the steps (unless skipped) if [[ "$SKIP_INSTALL" != true ]]; then install_deps fi if [[ "$SKIP_ZIP" != true ]]; then create_zip fi if [[ "$SKIP_UPLOAD" != true ]]; then upload_to_s3 fi echo "✅ All requested steps completed!"
How to Use the Script
Save the full script as deploy.sh, make it executable with chmod +x deploy.sh, then run it with these options:
Run all steps:
# Don't forget to set your S3 bucket path first! export S3_BUCKET_PATH="s3://your-bucket-name/path" ./deploy.shSkip the installation step:
export S3_BUCKET_PATH="s3://your-bucket-name/path" ./deploy.sh --skip-installSkip multiple steps (e.g., skip install and zip):
export S3_BUCKET_PATH="s3://your-bucket-name/path" ./deploy.sh --skip-install --skip-zipSkip only the upload step:
./deploy.sh --skip-upload
Key Notes for Beginners
- Strict Mode: The
set -euo pipefailline ensures your script exits immediately if any command fails, catches undefined variables, and propagates errors through pipes—this helps you spot bugs early. - Quoting Variables: Always wrap variables in quotes (like
"$ZIP_FILE") to avoid issues with spaces in filenames or paths. - Environment Variables: We use
export S3_BUCKET_PATHto pass the bucket path to the script. You could also modify the script to accept it as an argument (e.g.,--s3-bucket-path "s3://...") if you prefer—just add another case to the argument parser!
内容的提问来源于stack exchange,提问作者mlenthusiast

