zking2000 / NotePad

1 stars 0 forks source link

Shell module #38

Closed zking2000 closed 3 months ago

zking2000 commented 3 months ago

明白了,你需要一个可以在其他 shell 脚本中引用的模块,用于上传文件到 GCP bucket 和 GitHub。这是一个很好的想法,可以让你的代码更加模块化和可重用。我们来创建这样一个模块。

#!/bin/bash

# File: file_upload_module.sh

# Function to upload file to GCP bucket
upload_to_gcp() {
    local file_path="$1"
    local bucket_name="$2"
    local destination_path="$3"

    if [ -z "$file_path" ] || [ -z "$bucket_name" ] || [ -z "$destination_path" ]; then
        echo "Usage: upload_to_gcp <file_path> <bucket_name> <destination_path>"
        return 1
    fi

    if ! command -v gsutil &> /dev/null; then
        echo "Error: gsutil is not installed or not in PATH"
        return 1
    fi

    gsutil cp "$file_path" "gs://$bucket_name/$destination_path"
    return $?
}

# Function to upload file to GitHub
upload_to_github() {
    local file_path="$1"
    local repo_owner="$2"
    local repo_name="$3"
    local destination_path="$4"
    local commit_message="$5"
    local github_token="$6"

    if [ -z "$file_path" ] || [ -z "$repo_owner" ] || [ -z "$repo_name" ] || [ -z "$destination_path" ] || [ -z "$commit_message" ] || [ -z "$github_token" ]; then
        echo "Usage: upload_to_github <file_path> <repo_owner> <repo_name> <destination_path> <commit_message> <github_token>"
        return 1
    fi

    if ! command -v curl &> /dev/null; then
        echo "Error: curl is not installed or not in PATH"
        return 1
    fi

    local content=$(base64 -w 0 "$file_path")
    local api_url="https://api.github.com/repos/$repo_owner/$repo_name/contents/$destination_path"

    response=$(curl -s -X PUT "$api_url" \
         -H "Authorization: token $github_token" \
         -H "Accept: application/vnd.github.v3+json" \
         -d "{\"message\":\"$commit_message\",\"content\":\"$content\"}")

    if echo "$response" | grep -q '"content": {'; then
        echo "File uploaded successfully to GitHub"
        return 0
    else
        echo "Error uploading file to GitHub: $response"
        return 1
    fi
}

# Main function to demonstrate usage (can be removed in production)
main() {
    echo "This is a module file and should be sourced in other scripts, not run directly."
    echo "Example usage:"
    echo "  source ./file_upload_module.sh"
    echo "  upload_to_gcp \"local/file.txt\" \"my-bucket\" \"remote/path/file.txt\""
    echo "  upload_to_github \"local/file.txt\" \"owner\" \"repo\" \"path/in/repo/file.txt\" \"Commit message\" \"github_token\""
}

# Run main function only if the script is run directly (not sourced)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main
fi

这个模块(file_upload_module.sh)包含了两个主要函数:upload_to_gcpupload_to_github。你可以按照以下方式使用这个模块:

  1. 将这个脚本保存为 file_upload_module.sh

  2. 在你的主脚本中,你可以这样引用和使用这个模块:

#!/bin/bash

# 引用模块
source ./file_upload_module.sh

# 使用函数上传到 GCP
upload_to_gcp "local/file.txt" "my-bucket" "remote/path/file.txt"

# 使用函数上传到 GitHub
upload_to_github "local/file.txt" "owner" "repo" "path/in/repo/file.txt" "Commit message" "github_token"

使用注意事项:

  1. 确保 file_upload_module.sh 有执行权限:chmod +x file_upload_module.sh

  2. 对于 GCP 上传,你需要已经安装并配置好 gsutil

  3. 对于 GitHub 上传,你需要提供一个有效的 GitHub 个人访问令牌。

  4. 这个模块使用了一些 bash 的特性,如局部变量。确保你使用的是 bash,而不是其他 shell。

  5. 错误处理是基本的。在实际使用中,你可能需要根据具体情况增加更多的错误检查和日志记录。

  6. 对于大文件,特别是对 GitHub 的上传,这个脚本可能不太适用。GitHub 有文件大小限制,对于大文件,你可能需要考虑使用 Git LFS 或其他方法。

如果你需要对这个模块做任何修改或者有任何问题,请告诉我。

zking2000 commented 3 months ago

当然,我很乐意为你提供一个使用范例。以下是如何在另一个 shell 脚本中引用和使用这个模块的示例。

首先,让我们假设你已经创建了 file_upload_module.sh 文件,并将其保存在一个已知的位置,比如 /path/to/file_upload_module.sh

现在,让我们创建一个新的 shell 脚本,我们称之为 main_script.sh。这个脚本将引用我们的模块并使用其中的函数。以下是 main_script.sh 的内容:

#!/bin/bash

# 引用模块
source /path/to/file_upload_module.sh

# 设置变量
GCP_BUCKET="my-gcp-bucket"
GITHUB_OWNER="my-github-username"
GITHUB_REPO="my-repo-name"
GITHUB_TOKEN="your-github-personal-access-token"

# 函数:上传到 GCP 和 GitHub
upload_file() {
    local file_path="$1"
    local gcp_dest="$2"
    local github_dest="$3"
    local commit_message="$4"

    echo "Uploading $file_path to GCP bucket..."
    if upload_to_gcp "$file_path" "$GCP_BUCKET" "$gcp_dest"; then
        echo "Successfully uploaded to GCP bucket"
    else
        echo "Failed to upload to GCP bucket"
    fi

    echo "Uploading $file_path to GitHub..."
    if upload_to_github "$file_path" "$GITHUB_OWNER" "$GITHUB_REPO" "$github_dest" "$commit_message" "$GITHUB_TOKEN"; then
        echo "Successfully uploaded to GitHub"
    else
        echo "Failed to upload to GitHub"
    fi
}

# 主函数
main() {
    local file_to_upload="/path/to/local/file.txt"
    local gcp_destination="remote/path/file.txt"
    local github_destination="path/in/repo/file.txt"
    local commit_message="Upload file via script"

    upload_file "$file_to_upload" "$gcp_destination" "$github_destination" "$commit_message"
}

# 运行主函数
main

使用这个脚本的步骤如下:

  1. 确保 file_upload_module.sh 位于正确的路径(在这个例子中是 /path/to/file_upload_module.sh)。

  2. 将上面的内容保存为 main_script.sh

  3. 修改脚本中的变量以匹配你的实际设置:

    • GCP_BUCKET: 你的 Google Cloud Storage bucket 名称
    • GITHUB_OWNER: 你的 GitHub 用户名
    • GITHUB_REPO: 你要上传到的 GitHub 仓库名称
    • GITHUB_TOKEN: 你的 GitHub 个人访问令牌
  4. main 函数中,根据需要修改 file_to_uploadgcp_destinationgithub_destination 的值。

  5. 给脚本添加执行权限:

    chmod +x main_script.sh
  6. 运行脚本:

    ./main_script.sh

这个脚本会做以下事情:

  1. 引用 file_upload_module.sh 模块
  2. 设置必要的变量
  3. 定义一个 upload_file 函数,该函数使用模块中的 upload_to_gcpupload_to_github 函数
  4. main 函数中,指定要上传的文件和目标路径
  5. 调用 upload_file 函数来执行上传操作

这个例子展示了如何在另一个 shell 脚本中引用和使用你的模块。你可以根据需要further修改这个脚本,例如添加命令行参数解析,增加错误处理,或者添加更多的功能。

如果你有任何问题或需要进一步的说明,请随时告诉我。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

你的考虑非常正确。将敏感信息如 Token 直接硬编码在脚本中确实是不安全的做法。我们可以修改脚本,让它在运行时接受这些敏感信息作为参数。这样做既增加了安全性,也提高了脚本的灵活性。让我们来修改 main_script.sh

#!/bin/bash

# 引用模块
source /path/to/file_upload_module.sh

# 设置默认值
GCP_BUCKET=""
GITHUB_OWNER=""
GITHUB_REPO=""
GITHUB_TOKEN=""

# 函数:显示使用方法
show_usage() {
    echo "Usage: $0 -f <file_path> -g <gcp_bucket> -o <github_owner> -r <github_repo> -t <github_token> [-m <commit_message>]"
    echo "  -f: Local file path to upload"
    echo "  -g: GCP bucket name"
    echo "  -o: GitHub owner (username or organization)"
    echo "  -r: GitHub repository name"
    echo "  -t: GitHub personal access token"
    echo "  -m: Commit message (optional, default: 'Upload file via script')"
    exit 1
}

# 解析命令行参数
while getopts "f:g:o:r:t:m:" opt; do
    case $opt in
        f) FILE_PATH="$OPTARG" ;;
        g) GCP_BUCKET="$OPTARG" ;;
        o) GITHUB_OWNER="$OPTARG" ;;
        r) GITHUB_REPO="$OPTARG" ;;
        t) GITHUB_TOKEN="$OPTARG" ;;
        m) COMMIT_MESSAGE="$OPTARG" ;;
        *) show_usage ;;
    esac
done

# 检查必要参数是否提供
if [ -z "$FILE_PATH" ] || [ -z "$GCP_BUCKET" ] || [ -z "$GITHUB_OWNER" ] || [ -z "$GITHUB_REPO" ] || [ -z "$GITHUB_TOKEN" ]; then
    echo "Error: Missing required parameters."
    show_usage
fi

# 设置默认的提交信息
COMMIT_MESSAGE=${COMMIT_MESSAGE:-"Upload file via script"}

# 函数:上传到 GCP 和 GitHub
upload_file() {
    local file_path="$1"
    local gcp_dest="$2"
    local github_dest="$3"

    echo "Uploading $file_path to GCP bucket..."
    if upload_to_gcp "$file_path" "$GCP_BUCKET" "$gcp_dest"; then
        echo "Successfully uploaded to GCP bucket"
    else
        echo "Failed to upload to GCP bucket"
    fi

    echo "Uploading $file_path to GitHub..."
    if upload_to_github "$file_path" "$GITHUB_OWNER" "$GITHUB_REPO" "$github_dest" "$COMMIT_MESSAGE" "$GITHUB_TOKEN"; then
        echo "Successfully uploaded to GitHub"
    else
        echo "Failed to upload to GitHub"
    fi
}

# 主函数
main() {
    local file_name=$(basename "$FILE_PATH")
    local gcp_destination="uploads/$file_name"
    local github_destination="uploads/$file_name"

    upload_file "$FILE_PATH" "$gcp_destination" "$github_destination"
}

# 运行主函数
main

使用这个更新后的脚本的步骤如下:

  1. 保存上述内容为 main_script.sh

  2. 给脚本添加执行权限:

    chmod +x main_script.sh
  3. 运行脚本,提供所有必要的参数:

    ./main_script.sh -f /path/to/local/file.txt -g my-gcp-bucket -o my-github-username -r my-repo-name -t your-github-token

    你也可以添加可选的提交信息:

    ./main_script.sh -f /path/to/local/file.txt -g my-gcp-bucket -o my-github-username -r my-repo-name -t your-github-token -m "Custom commit message"

这个更新后的脚本有以下改进:

  1. 所有敏感信息和可变参数现在都通过命令行参数传入,而不是硬编码在脚本中。

  2. 使用 getopts 来解析命令行参数,这使得脚本更加灵活和用户友好。

  3. 添加了参数检查,确保所有必要的信息都被提供。

  4. 提供了使用说明(show_usage 函数),当参数不正确时会显示。

  5. 文件目标路径现在基于输入文件名自动生成,增加了灵活性。

  6. 提交信息现在是一个可选参数,有默认值。

这种方法大大提高了脚本的安全性和可重用性。你可以安全地在不同的环境中使用这个脚本,而不用担心敏感信息泄露。

如果你需要进一步的修改或有任何其他问题,请随时告诉我。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

理解了,你希望在另一个 shell 脚本中引用这个模块,并且将上传文件的方法封装在一个单独的函数中。这是一个很好的做法,可以提高代码的可读性和可维护性。我会为你创建一个这样的示例。

首先,让我们假设你的 file_upload_module.sh 位于 /path/to/file_upload_module.sh

现在,我们来创建一个新的脚本,我们称之为 upload_handler.sh。这个脚本将引用我们的模块,并包含一个封装了上传逻辑的函数。

#!/bin/bash

# 引用模块
source /path/to/file_upload_module.sh

# 封装上传逻辑的函数
upload_file_to_platforms() {
    local file_path="$1"
    local gcp_bucket="$2"
    local github_owner="$3"
    local github_repo="$4"
    local github_token="$5"
    local commit_message="${6:-Upload file via script}"  # 使用默认提交信息

    # 生成目标路径
    local file_name=$(basename "$file_path")
    local gcp_destination="uploads/$file_name"
    local github_destination="uploads/$file_name"

    # 上传到 GCP
    echo "Uploading $file_path to GCP bucket $gcp_bucket..."
    if upload_to_gcp "$file_path" "$gcp_bucket" "$gcp_destination"; then
        echo "Successfully uploaded to GCP bucket"
    else
        echo "Failed to upload to GCP bucket"
        return 1
    fi

    # 上传到 GitHub
    echo "Uploading $file_path to GitHub repository $github_owner/$github_repo..."
    if upload_to_github "$file_path" "$github_owner" "$github_repo" "$github_destination" "$commit_message" "$github_token"; then
        echo "Successfully uploaded to GitHub"
    else
        echo "Failed to upload to GitHub"
        return 1
    fi

    echo "File $file_path uploaded successfully to both platforms."
    return 0
}

# 主函数 - 这里你可以根据需要调用 upload_file_to_platforms 函数
main() {
    local file_to_upload="/path/to/your/file.txt"
    local gcp_bucket="your-gcp-bucket-name"
    local github_owner="your-github-username"
    local github_repo="your-repo-name"
    local github_token="your-github-token"
    local commit_message="Uploading file via script"

    if upload_file_to_platforms "$file_to_upload" "$gcp_bucket" "$github_owner" "$github_repo" "$github_token" "$commit_message"; then
        echo "Main: Upload process completed successfully."
    else
        echo "Main: Upload process failed."
        exit 1
    fi

    # 这里你可以添加更多的逻辑,比如处理多个文件等
}

# 运行主函数
main

这个脚本 (upload_handler.sh) 做了以下几件事:

  1. 引用了 file_upload_module.sh 模块。

  2. 定义了一个 upload_file_to_platforms 函数,该函数封装了上传到 GCP 和 GitHub 的逻辑。

  3. main 函数中,展示了如何调用 upload_file_to_platforms 函数。

  4. 你可以根据需要修改 main 函数,例如处理多个文件或添加其他逻辑。

使用这个脚本的步骤:

  1. 保存上述内容为 upload_handler.sh

  2. 给脚本添加执行权限:

    chmod +x upload_handler.sh
  3. 在使用之前,确保修改 main 函数中的变量,使其匹配你的实际设置:

    • file_to_upload
    • gcp_bucket
    • github_owner
    • github_repo
    • github_token
    • commit_message
  4. 运行脚本:

    ./upload_handler.sh

这个示例展示了如何在另一个 shell 脚本中引用你的模块,并将上传逻辑封装在一个单独的函数中。这种方法有几个优点:

如果你想进一步改进这个脚本,可以考虑添加错误处理、日志记录、或者使用命令行参数来接收输入,而不是在脚本中硬编码值。如果你需要任何修改或有其他问题,请随时告诉我。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

你的要求很合理。将上传到 GCP 和上传到 GitHub 的功能分开确实可以提供更大的灵活性。让我为你创建一个新的示例,展示如何在另一个脚本中引用模块,并分别使用上传到 GCP 和上传到 GitHub 的功能。

首先,假设 file_upload_module.sh 位于 /path/to/file_upload_module.sh

现在,让我们创建一个新的脚本,称为 flexible_upload_handler.sh

#!/bin/bash

# 引用模块
source /path/to/file_upload_module.sh

# 封装上传到 GCP 的函数
upload_to_gcp_bucket() {
    local file_path="$1"
    local gcp_bucket="$2"
    local gcp_destination="${3:-uploads/$(basename "$file_path")}"

    echo "Uploading $file_path to GCP bucket $gcp_bucket..."
    if upload_to_gcp "$file_path" "$gcp_bucket" "$gcp_destination"; then
        echo "Successfully uploaded to GCP bucket"
        return 0
    else
        echo "Failed to upload to GCP bucket"
        return 1
    fi
}

# 封装上传到 GitHub 的函数
upload_to_github_repo() {
    local file_path="$1"
    local github_owner="$2"
    local github_repo="$3"
    local github_token="$4"
    local github_destination="${5:-uploads/$(basename "$file_path")}"
    local commit_message="${6:-Upload file via script}"

    echo "Uploading $file_path to GitHub repository $github_owner/$github_repo..."
    if upload_to_github "$file_path" "$github_owner" "$github_repo" "$github_destination" "$commit_message" "$github_token"; then
        echo "Successfully uploaded to GitHub"
        return 0
    else
        echo "Failed to upload to GitHub"
        return 1
    fi
}

# 主函数 - 这里你可以根据需要分别调用 GCP 和 GitHub 上传函数
main() {
    local file_to_upload="/path/to/your/file.txt"
    local gcp_bucket="your-gcp-bucket-name"
    local github_owner="your-github-username"
    local github_repo="your-repo-name"
    local github_token="your-github-token"

    # 上传到 GCP
    if upload_to_gcp_bucket "$file_to_upload" "$gcp_bucket"; then
        echo "Main: GCP upload process completed successfully."
    else
        echo "Main: GCP upload process failed."
    fi

    # 上传到 GitHub
    if upload_to_github_repo "$file_to_upload" "$github_owner" "$github_repo" "$github_token"; then
        echo "Main: GitHub upload process completed successfully."
    else
        echo "Main: GitHub upload process failed."
    fi

    # 这里你可以添加更多的逻辑,比如处理多个文件,或者根据条件决定是否上传到某个平台
}

# 运行主函数
main

这个新的脚本 (flexible_upload_handler.sh) 做了以下几件事:

  1. 引用了 file_upload_module.sh 模块。

  2. 定义了两个单独的函数:

    • upload_to_gcp_bucket: 封装了上传到 GCP 的逻辑。
    • upload_to_github_repo: 封装了上传到 GitHub 的逻辑。
  3. main 函数中,分别调用了这两个函数,展示了如何独立使用它们。

  4. 每个函数都有自己的错误处理和返回值,使得调用者可以根据需要处理成功或失败的情况。

使用这个脚本的步骤:

  1. 保存上述内容为 flexible_upload_handler.sh

  2. 给脚本添加执行权限:

    chmod +x flexible_upload_handler.sh
  3. 在使用之前,确保修改 main 函数中的变量,使其匹配你的实际设置:

    • file_to_upload
    • gcp_bucket
    • github_owner
    • github_repo
    • github_token
  4. 运行脚本:

    ./flexible_upload_handler.sh

这个示例的优点包括:

如果你想进一步改进这个脚本,可以考虑:

如果你需要任何修改或有其他问题,请随时告诉我。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

非常抱歉我之前理解错了。您是希望我重写模块中的 GitHub 上传方法,而不是主脚本。这是一个很好的建议,可以让模块更加灵活和强大。让我们重写 file_upload_module.sh 中的 GitHub 上传方法,使用 Git 命令来实现。

#!/bin/bash

# 上传到 GCP 的函数(保持不变)
upload_to_gcp() {
    local file_path="$1"
    local bucket_name="$2"
    local destination_path="$3"

    if [ -z "$file_path" ] || [ -z "$bucket_name" ] || [ -z "$destination_path" ]; then
        echo "Usage: upload_to_gcp <file_path> <bucket_name> <destination_path>"
        return 1
    fi

    if ! command -v gsutil &> /dev/null; then
        echo "Error: gsutil is not installed or not in PATH"
        return 1
    fi

    gsutil cp "$file_path" "gs://$bucket_name/$destination_path"
    return $?
}

# 使用 Git 命令重写上传到 GitHub 的函数
upload_to_github() {
    local file_path="$1"
    local github_owner="$2"
    local github_repo="$3"
    local github_branch="$4"
    local commit_message="$5"

    if [ -z "$file_path" ] || [ -z "$github_owner" ] || [ -z "$github_repo" ] || [ -z "$github_branch" ] || [ -z "$commit_message" ]; then
        echo "Usage: upload_to_github <file_path> <github_owner> <github_repo> <github_branch> <commit_message>"
        return 1
    fi

    if ! command -v git &> /dev/null; then
        echo "Error: git is not installed or not in PATH"
        return 1
    fi

    # 创建临时目录
    local temp_dir=$(mktemp -d)
    echo "Created temporary directory: $temp_dir"

    # 克隆仓库
    echo "Cloning repository..."
    if ! git clone "https://github.com/$github_owner/$github_repo.git" "$temp_dir"; then
        echo "Failed to clone repository"
        rm -rf "$temp_dir"
        return 1
    fi

    # 切换到仓库目录
    cd "$temp_dir"

    # 切换到指定分支
    echo "Switching to branch: $github_branch"
    if ! git checkout "$github_branch"; then
        echo "Failed to switch to branch $github_branch"
        cd - > /dev/null
        rm -rf "$temp_dir"
        return 1
    fi

    # 复制文件到仓库
    echo "Copying file to repository..."
    cp "$file_path" .

    # 添加文件到 Git
    local file_name=$(basename "$file_path")
    echo "Adding file to Git..."
    git add "$file_name"

    # 提交更改
    echo "Committing changes..."
    if ! git commit -m "$commit_message"; then
        echo "Failed to commit changes"
        cd - > /dev/null
        rm -rf "$temp_dir"
        return 1
    fi

    # 推送到 GitHub
    echo "Pushing to GitHub..."
    if ! git push origin "$github_branch"; then
        echo "Failed to push to GitHub"
        cd - > /dev/null
        rm -rf "$temp_dir"
        return 1
    fi

    # 清理
    cd - > /dev/null
    rm -rf "$temp_dir"

    echo "Successfully uploaded to GitHub"
    return 0
}

这个更新后的模块有以下几个关键变化:

  1. upload_to_github 函数现在使用 Git 命令而不是 API 调用来上传文件。

  2. 函数参数有所变化,移除了 github_token,添加了 github_branch

  3. 这个方法会克隆整个仓库到一个临时目录,添加文件,提交更改,然后推送回 GitHub。

  4. 增加了更多的错误处理和日志输出。

使用这个模块的步骤:

  1. 将上述内容保存为 file_upload_module.sh

  2. 在你的主脚本中,你可以这样使用这个模块:

#!/bin/bash

# 引用模块
source /path/to/file_upload_module.sh

# 使用函数上传到 GCP(与之前相同)
upload_to_gcp "local/file.txt" "my-bucket" "remote/path/file.txt"

# 使用新的 Git 方法上传到 GitHub
upload_to_github "local/file.txt" "owner" "repo" "main" "Upload file via Git"

注意事项:

  1. 确保你的系统上安装了 Git。

  2. 这个方法假设你已经设置了 Git 的认证方式(比如 SSH 密钥或存储的凭证)。如果没有,你可能需要在推送时输入用户名和密码。

  3. 对于大型仓库,克隆操作可能会花费较长时间。

  4. 这个方法会在每次上传时克隆整个仓库,这可能不是最高效的方式,特别是对于频繁的小文件上传。

  5. 你可能需要在使用这个模块的脚本中添加错误处理,以应对上传失败的情况。

如果你需要进一步的修改或有任何问题,请告诉我。我可以帮你调整模块以满足特定的需求,比如添加更多的配置选项或优化性能。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

您说得对。既然我们修改了模块中的方法,我们也需要更新在其他脚本中的引用。让我给您一个更新后的范例,展示如何在另一个脚本中正确地使用这个修改后的模块。

#!/bin/bash

# 引用修改后的模块
source /path/to/file_upload_module.sh

# 封装上传到 GCP 的函数
upload_to_gcp_bucket() {
    local file_path="$1"
    local gcp_bucket="$2"
    local gcp_destination="${3:-uploads/$(basename "$file_path")}"

    echo "Uploading $file_path to GCP bucket $gcp_bucket..."
    if upload_to_gcp "$file_path" "$gcp_bucket" "$gcp_destination"; then
        echo "Successfully uploaded to GCP bucket"
        return 0
    else
        echo "Failed to upload to GCP bucket"
        return 1
    fi
}

# 封装上传到 GitHub 的函数(使用新的 Git 方法)
upload_to_github_repo() {
    local file_path="$1"
    local github_owner="$2"
    local github_repo="$3"
    local github_branch="$4"
    local commit_message="$5"

    echo "Uploading $file_path to GitHub repository $github_owner/$github_repo on branch $github_branch..."
    if upload_to_github "$file_path" "$github_owner" "$github_repo" "$github_branch" "$commit_message"; then
        echo "Successfully uploaded to GitHub"
        return 0
    else
        echo "Failed to upload to GitHub"
        return 1
    fi
}

# 主函数 - 这里你可以根据需要分别调用 GCP 和 GitHub 上传函数
main() {
    local file_to_upload="/path/to/your/file.txt"
    local gcp_bucket="your-gcp-bucket-name"
    local github_owner="your-github-username"
    local github_repo="your-repo-name"
    local github_branch="main"
    local commit_message="Upload file via updated script"

    # 上传到 GCP
    if upload_to_gcp_bucket "$file_to_upload" "$gcp_bucket"; then
        echo "Main: GCP upload process completed successfully."
    else
        echo "Main: GCP upload process failed."
    fi

    # 上传到 GitHub(使用新的方法)
    if upload_to_github_repo "$file_to_upload" "$github_owner" "$github_repo" "$github_branch" "$commit_message"; then
        echo "Main: GitHub upload process completed successfully."
    else
        echo "Main: GitHub upload process failed."
    fi

    # 这里你可以添加更多的逻辑,比如处理多个文件,或者根据条件决定是否上传到某个平台
}

# 运行主函数
main

这个更新后的脚本有以下几个关键变化:

  1. upload_to_github_repo 函数现在接受新的参数集,包括 github_branchcommit_message,而不再需要 github_token

  2. 在调用 upload_to_github 时,我们传入了新的参数集,包括分支名和提交信息。

  3. 主函数 main 中,我们添加了 github_branchcommit_message 变量,以适应新的函数调用。

使用这个脚本的步骤:

  1. 确保你已经更新了 file_upload_module.sh,使用之前提供的新版本。

  2. 将上述内容保存为 updated_flexible_upload_handler.sh

  3. 给脚本添加执行权限:

    chmod +x updated_flexible_upload_handler.sh
  4. 在使用之前,修改 main 函数中的变量,使其匹配你的实际设置:

    • file_to_upload
    • gcp_bucket
    • github_owner
    • github_repo
    • github_branch
    • commit_message
  5. 运行脚本:

    ./updated_flexible_upload_handler.sh

注意事项:

  1. 确保你的系统上安装了 Git,并且已经配置了 GitHub 认证(通过 SSH 密钥或者存储的凭证)。

  2. 这个脚本假设你有权限推送到指定的 GitHub 仓库和分支。

  3. 对于大型仓库或频繁的小文件上传,你可能需要考虑优化 GitHub 上传过程,例如保持一个本地克隆并定期更新,而不是每次都重新克隆。

  4. 考虑添加更多的错误处理和日志记录,特别是在处理多个文件或在生产环境中使用时。

如果你需要进一步的修改或有任何问题,请告诉我。我可以帮你进一步调整脚本以满足特定的需求,比如添加命令行参数解析,或者实现批量文件处理。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

您说得对,我忽略了使用 Token 的重要性。使用 Token 确实是一种更安全、更灵活的认证方式。我们来修改模块中的 GitHub 上传方法,使其使用 Token 进行认证。

#!/bin/bash

# 上传到 GCP 的函数(保持不变)
upload_to_gcp() {
    local file_path="$1"
    local bucket_name="$2"
    local destination_path="$3"

    if [ -z "$file_path" ] || [ -z "$bucket_name" ] || [ -z "$destination_path" ]; then
        echo "Usage: upload_to_gcp <file_path> <bucket_name> <destination_path>"
        return 1
    fi

    if ! command -v gsutil &> /dev/null; then
        echo "Error: gsutil is not installed or not in PATH"
        return 1
    fi

    gsutil cp "$file_path" "gs://$bucket_name/$destination_path"
    return $?
}

# 使用 Git 命令和 Token 认证重写上传到 GitHub 的函数
upload_to_github() {
    local file_path="$1"
    local github_owner="$2"
    local github_repo="$3"
    local github_branch="$4"
    local commit_message="$5"
    local github_token="$6"

    if [ -z "$file_path" ] || [ -z "$github_owner" ] || [ -z "$github_repo" ] || [ -z "$github_branch" ] || [ -z "$commit_message" ] || [ -z "$github_token" ]; then
        echo "Usage: upload_to_github <file_path> <github_owner> <github_repo> <github_branch> <commit_message> <github_token>"
        return 1
    fi

    if ! command -v git &> /dev/null; then
        echo "Error: git is not installed or not in PATH"
        return 1
    fi

    # 创建临时目录
    local temp_dir=$(mktemp -d)
    echo "Created temporary directory: $temp_dir"

    # 克隆仓库(使用 Token)
    echo "Cloning repository..."
    if ! git clone "https://${github_token}@github.com/${github_owner}/${github_repo}.git" "$temp_dir"; then
        echo "Failed to clone repository"
        rm -rf "$temp_dir"
        return 1
    fi

    # 切换到仓库目录
    cd "$temp_dir"

    # 设置 Git 用户信息(使用 GitHub 的 no-reply 邮箱)
    git config user.name "GitHub Actions"
    git config user.email "github-actions[bot]@users.noreply.github.com"

    # 切换到指定分支
    echo "Switching to branch: $github_branch"
    if ! git checkout "$github_branch"; then
        echo "Failed to switch to branch $github_branch"
        cd - > /dev/null
        rm -rf "$temp_dir"
        return 1
    fi

    # 复制文件到仓库
    echo "Copying file to repository..."
    cp "$file_path" .

    # 添加文件到 Git
    local file_name=$(basename "$file_path")
    echo "Adding file to Git..."
    git add "$file_name"

    # 提交更改
    echo "Committing changes..."
    if ! git commit -m "$commit_message"; then
        echo "Failed to commit changes"
        cd - > /dev/null
        rm -rf "$temp_dir"
        return 1
    fi

    # 推送到 GitHub(使用 Token)
    echo "Pushing to GitHub..."
    if ! git push "https://${github_token}@github.com/${github_owner}/${github_repo}.git" "$github_branch"; then
        echo "Failed to push to GitHub"
        cd - > /dev/null
        rm -rf "$temp_dir"
        return 1
    fi

    # 清理
    cd - > /dev/null
    rm -rf "$temp_dir"

    echo "Successfully uploaded to GitHub"
    return 0
}

这个更新后的模块有以下几个关键变化:

  1. upload_to_github 函数现在接受一个额外的参数 github_token

  2. 在克隆仓库和推送更改时,我们使用 Token 进行认证,而不是依赖于预先配置的 SSH 密钥或存储的凭证。

  3. 我们设置了 Git 用户信息,使用 GitHub Actions 的默认配置。这在使用 Token 认证时很有用,因为 Token 不包含用户信息。

  4. 在错误处理和日志输出中,我们小心地不暴露 Token。

现在,让我们更新主脚本以适应这些变化:

#!/bin/bash

# 引用修改后的模块
source /path/to/file_upload_module.sh

# 封装上传到 GCP 的函数(保持不变)
upload_to_gcp_bucket() {
    local file_path="$1"
    local gcp_bucket="$2"
    local gcp_destination="${3:-uploads/$(basename "$file_path")}"

    echo "Uploading $file_path to GCP bucket $gcp_bucket..."
    if upload_to_gcp "$file_path" "$gcp_bucket" "$gcp_destination"; then
        echo "Successfully uploaded to GCP bucket"
        return 0
    else
        echo "Failed to upload to GCP bucket"
        return 1
    fi
}

# 封装上传到 GitHub 的函数(使用新的 Token-based 方法)
upload_to_github_repo() {
    local file_path="$1"
    local github_owner="$2"
    local github_repo="$3"
    local github_branch="$4"
    local commit_message="$5"
    local github_token="$6"

    echo "Uploading $file_path to GitHub repository $github_owner/$github_repo on branch $github_branch..."
    if upload_to_github "$file_path" "$github_owner" "$github_repo" "$github_branch" "$commit_message" "$github_token"; then
        echo "Successfully uploaded to GitHub"
        return 0
    else
        echo "Failed to upload to GitHub"
        return 1
    fi
}

# 主函数 - 这里你可以根据需要分别调用 GCP 和 GitHub 上传函数
main() {
    local file_to_upload="/path/to/your/file.txt"
    local gcp_bucket="your-gcp-bucket-name"
    local github_owner="your-github-username"
    local github_repo="your-repo-name"
    local github_branch="main"
    local commit_message="Upload file via updated script"
    local github_token="your-github-personal-access-token"

    # 上传到 GCP
    if upload_to_gcp_bucket "$file_to_upload" "$gcp_bucket"; then
        echo "Main: GCP upload process completed successfully."
    else
        echo "Main: GCP upload process failed."
    fi

    # 上传到 GitHub(使用新的 Token-based 方法)
    if upload_to_github_repo "$file_to_upload" "$github_owner" "$github_repo" "$github_branch" "$commit_message" "$github_token"; then
        echo "Main: GitHub upload process completed successfully."
    else
        echo "Main: GitHub upload process failed."
    fi

    # 这里你可以添加更多的逻辑,比如处理多个文件,或者根据条件决定是否上传到某个平台
}

# 运行主函数
main

使用这个更新后的脚本的步骤:

  1. 确保你已经更新了 file_upload_module.sh,使用新版本的 Token-based GitHub 上传方法。

  2. 将上述内容保存为 updated_flexible_upload_handler.sh

  3. 给脚本添加执行权限:

    chmod +x updated_flexible_upload_handler.sh
  4. 在使用之前,修改 main 函数中的变量,使其匹配你的实际设置,特别是 github_token

  5. 运行脚本:

    ./updated_flexible_upload_handler.sh

注意事项:

  1. 确保你的 GitHub Token 有足够的权限来推送到指定的仓库。

  2. 不要在脚本中硬编码 Token。相反,考虑使用环境变量或安全的密钥管理系统来存储和获取 Token。

  3. 如果你将这个脚本用于自动化流程(如 CI/CD),确保 Token 被安全地存储和传递。

  4. 定期轮换你的 GitHub Token 以增加安全性。

  5. 考虑添加更多的错误处理和日志记录,特别是在处理敏感操作时。

这个更新后的版本应该能更安全地处理 GitHub 上传,同时保持了脚本的灵活性和功能性。如果你需要进一步的修改或有任何问题,请随时告诉我。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

在 shell 脚本中获取文件的绝对路径有几种方法。我将为您介绍最常用和最可靠的方法。

#!/bin/bash

# 方法 1: 使用 realpath 命令
get_absolute_path_realpath() {
    local file_path="$1"
    if command -v realpath &> /dev/null; then
        realpath "$file_path"
    else
        echo "realpath command not found"
        return 1
    fi
}

# 方法 2: 使用 readlink 命令
get_absolute_path_readlink() {
    local file_path="$1"
    if command -v readlink &> /dev/null; then
        readlink -f "$file_path"
    else
        echo "readlink command not found"
        return 1
    fi
}

# 方法 3: 使用 pwd 和 dirname 命令
get_absolute_path_pwd() {
    local file_path="$1"
    local dir=$(dirname "$file_path")
    local file=$(basename "$file_path")
    local old_pwd=$(pwd)
    cd "$dir" || return 1
    local abs_dir=$(pwd -P)
    cd "$old_pwd" || return 1
    echo "$abs_dir/$file"
}

# 主函数:演示使用这些方法
main() {
    local file_path="$1"

    if [ -z "$file_path" ]; then
        echo "Usage: $0 <file_path>"
        return 1
    fi

    echo "Using realpath:"
    get_absolute_path_realpath "$file_path"

    echo "Using readlink:"
    get_absolute_path_readlink "$file_path"

    echo "Using pwd and dirname:"
    get_absolute_path_pwd "$file_path"
}

# 运行主函数
main "$@"

这个脚本提供了三种获取文件绝对路径的方法:

  1. 使用 realpath 命令
  2. 使用 readlink 命令
  3. 使用 pwddirname 命令的组合

使用这个脚本的步骤:

  1. 将上述内容保存为 get_absolute_path.sh

  2. 给脚本添加执行权限:

    chmod +x get_absolute_path.sh
  3. 运行脚本,传入你想要获取绝对路径的文件路径:

    ./get_absolute_path.sh /path/to/your/file.txt

注意事项:

  1. realpathreadlink 命令可能不是在所有系统上都可用。特别是在一些较旧的系统上,这些命令可能缺失。

  2. 第三种方法(使用 pwddirname)是最便携的,因为它使用的是大多数 UNIX 系统都有的基本命令。

  3. 这个脚本会尝试所有三种方法。在实际使用中,你可能只需要选择一种最适合你系统的方法。

  4. 对于符号链接,realpathreadlink -f 会返回链接指向的实际文件的路径,而不是链接本身的路径。

  5. 如果你只需要在你的脚本中使用其中一种方法,你可以直接复制相应的函数到你的脚本中。

在你的上传脚本中,你可以使用这些方法中的一个来确保你总是使用文件的绝对路径。例如:

file_to_upload=$(get_absolute_path_pwd "/path/to/your/file.txt")

这样可以确保无论脚本从哪里运行,都能正确地找到并上传指定的文件。

如果你有任何疑问或需要进一步的解释,请随时告诉我。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

当然可以。我们可以使用 shell 脚本来实现类似的功能。Shell 脚本在处理系统级任务和与 kubectl 命令行工具交互方面非常有效。这里是一个使用 shell 脚本的解决方案:

#!/bin/bash

# 设置变量
BACKUP_DIR="gke_backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_PATH="${BACKUP_DIR}/backup_${TIMESTAMP}"

# 创建备份目录
mkdir -p "$BACKUP_PATH"

# 获取所有命名空间
namespaces=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}')

# 获取所有资源类型
resource_types=$(kubectl api-resources --verbs=list --namespaced -o name | sort | uniq)

# 备份函数
backup_resources() {
    local namespace=$1
    local resource_type=$2

    echo "Backing up $resource_type in namespace $namespace"

    # 获取资源并保存到文件
    kubectl get "$resource_type" -n "$namespace" -o json | jq '.items' > "$BACKUP_PATH/${namespace}_${resource_type}.json"
}

# 主备份循环
for namespace in $namespaces
do
    echo "Processing namespace: $namespace"
    for resource_type in $resource_types
    do
        backup_resources "$namespace" "$resource_type"
    done
done

# 备份集群级资源
cluster_resource_types=$(kubectl api-resources --verbs=list --namespaced=false -o name | sort | uniq)

for resource_type in $cluster_resource_types
do
    echo "Backing up cluster-level resource: $resource_type"
    kubectl get "$resource_type" -o json | jq '.items' > "$BACKUP_PATH/cluster_${resource_type}.json"
done

echo "Backup completed: $BACKUP_PATH"

这个 shell 脚本的主要功能包括:

  1. 自动创建一个带时间戳的备份目录。
  2. 获取所有命名空间和资源类型。
  3. 遍历每个命名空间和资源类型,使用 kubectl get 命令获取资源,并将结果保存为 JSON 文件。
  4. 备份集群级(非命名空间)资源。

使用这个脚本的优势:

  1. 不需要额外的 Python 依赖,只需要 kubectl 和 jq(用于 JSON 处理)。
  2. 直接使用 kubectl 命令,可以轻松获取所有资源类型。
  3. 灵活性强,可以轻松添加或修改备份逻辑。

要使用这个脚本:

  1. 确保您已安装 kubectl 和 jq。
  2. 将脚本保存为文件,例如 gke_backup.sh
  3. 给脚本添加执行权限:chmod +x gke_backup.sh
  4. 确保您的 kubectl 已正确配置,可以访问目标 GKE 集群。
  5. 运行脚本:./gke_backup.sh

脚本会在当前目录下创建一个 gke_backups 文件夹,并在其中生成带有时间戳的备份文件。

这个脚本提供了一个基本的框架,您可以根据需要进行自定义,比如:

您需要我解释脚本的某个特定部分,或者对脚本进行任何修改吗?​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

您提出了一个很好的问题。确实,有些资源可能是空的或者没有实际内容。我们可以修改之前的shell脚本来筛选出有内容的资源。这里有一个改进的版本:

#!/bin/bash

# 设置变量
BACKUP_DIR="gke_backups"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_PATH="${BACKUP_DIR}/backup_${TIMESTAMP}"

# 创建备份目录
mkdir -p "$BACKUP_PATH"

# 获取所有命名空间
namespaces=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}')

# 获取所有资源类型
resource_types=$(kubectl api-resources --verbs=list --namespaced -o name | sort | uniq)

# 备份函数
backup_resources() {
    local namespace=$1
    local resource_type=$2

    echo "Checking $resource_type in namespace $namespace"

    # 获取资源并检查是否为空
    resources=$(kubectl get "$resource_type" -n "$namespace" -o json | jq '.items')

    # 检查资源是否为空数组
    if [ "$resources" != "[]" ]; then
        echo "Backing up $resource_type in namespace $namespace"
        echo "$resources" > "$BACKUP_PATH/${namespace}_${resource_type}.json"
    else
        echo "Skipping empty resource $resource_type in namespace $namespace"
    fi
}

# 主备份循环
for namespace in $namespaces
do
    echo "Processing namespace: $namespace"
    for resource_type in $resource_types
    do
        backup_resources "$namespace" "$resource_type"
    done
done

# 备份集群级资源
cluster_resource_types=$(kubectl api-resources --verbs=list --namespaced=false -o name | sort | uniq)

for resource_type in $cluster_resource_types
do
    echo "Checking cluster-level resource: $resource_type"
    resources=$(kubectl get "$resource_type" -o json | jq '.items')

    if [ "$resources" != "[]" ]; then
        echo "Backing up cluster-level resource: $resource_type"
        echo "$resources" > "$BACKUP_PATH/cluster_${resource_type}.json"
    else
        echo "Skipping empty cluster-level resource: $resource_type"
    fi
done

echo "Backup completed: $BACKUP_PATH"

这个改进的脚本主要做了以下更改:

  1. backup_resources 函数中,我们先获取资源,然后检查它是否为空数组。

  2. 使用 jq 命令来解析 JSON 并检查 .items 数组是否为空。

  3. 只有当资源不为空时,才会创建备份文件。

  4. 对集群级资源也进行了类似的处理。

  5. 添加了更多的输出信息,显示哪些资源被跳过,哪些被备份。

这个脚本的主要优点是:

  1. 只备份有实际内容的资源,节省存储空间。
  2. 提供更清晰的输出,让您了解哪些资源被备份,哪些被跳过。
  3. 保持了原有的灵活性和全面性。

使用方法与之前相同:

  1. 保存脚本为文件,例如 gke_backup_filtered.sh
  2. 添加执行权限:chmod +x gke_backup_filtered.sh
  3. 确保 kubectl 配置正确,可以访问目标 GKE 集群。
  4. 运行脚本:./gke_backup_filtered.sh

这个脚本会创建一个只包含非空资源的备份。如果您想进一步优化或添加功能,比如:

我可以帮您进行这些修改。您对这个改进的脚本有什么想法或其他需求吗?​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago

您提出了一个很好的观点。确实,我提供的改进方案需要安装额外的工具,这可能在某些环境中不太方便。让我们考虑一个不需要额外工具的改进方案,只使用基本的 Bash 功能:

#!/usr/bin/env bash

MAX_JOBS=10
TIMEOUT=600

function compare_resource_counts() {
    echo "Comparing resource counts..."

    local GREEN='\033[0;32m'
    local RED='\033[0;31m'
    local NO_COLOR='\033[0m'

    # 使用命名管道进行并行处理
    local pipe=$(mktemp -u)
    mkfifo "$pipe"

    # 启动后台进程读取结果
    process_results < "$pipe" &
    local reader_pid=$!

    local job_count=0
    for NS in $NAMESPACES; do
        for RESOURCE in "${RESOURCES[@]}"; do
            (
                # 计算环境中的资源数量
                ENV_COUNT=$(kubectl get "$RESOURCE" -n "$NS" --no-headers 2>/dev/null | wc -l)

                # 计算YAML文件中的资源数量
                FILE_COUNT=$(find "$PROJECT_ID-$(date +%Y%m%d)/$CLUSTER_NAME/$NS/$RESOURCE" -name "*.yaml" 2>/dev/null | wc -l)

                # 输出结果到命名管道
                echo "$NS:$RESOURCE:$ENV_COUNT:$FILE_COUNT" > "$pipe"
            ) &

            ((job_count++))
            if ((job_count >= MAX_JOBS)); then
                wait -n
                ((job_count--))
            fi
        done
    done

    # 等待所有后台任务完成
    wait

    # 关闭命名管道,结束读取进程
    exec {pipe}>&-
    wait $reader_pid

    # 清理临时文件
    rm -f "$pipe"
}

function process_results() {
    while IFS=: read -r NS RESOURCE ENV_COUNT FILE_COUNT; do
        if [ "$ENV_COUNT" -eq "$FILE_COUNT" ]; then
            echo -e "Namespace: $NS, $RESOURCE: ${GREEN}$ENV_COUNT MATCH${NO_COLOR}"
        else
            echo -e "Namespace: $NS, $RESOURCE: ${RED}$ENV_COUNT MISMATCH (Files: $FILE_COUNT)${NO_COLOR}"
        fi
    done
}

# 主程序
NAMESPACES=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}')
RESOURCES=("deployments" "services" "configmaps" "secrets")

compare_resource_counts

这个改进版本有以下特点:

  1. 不需要额外工具:仅使用标准的 Bash 功能和常见的 Unix 工具。

  2. 并行处理:使用 Bash 的后台作业功能 (&) 来并行执行任务。

  3. 作业控制:通过 MAX_JOBS 变量限制同时运行的作业数量。

  4. 命名管道:使用命名管道 (FIFO) 来收集并处理并行任务的结果。

  5. 资源效率:动态创建和销毁命名管道,避免文件系统资源浪费。

  6. 错误处理:将可能的错误输出重定向到 /dev/null,避免干扰结果显示。

这个方案在不需要安装额外工具的情况下,仍然能够有效地并行处理资源比较任务,同时保持了代码的清晰度和可维护性。它应该能在大多数 Unix-like 系统上运行,包括大多数 Linux 发行版和 macOS。​​​​​​​​​​​​​​​​

zking2000 commented 3 months ago
#!/usr/bin/env bash

function compare_resource_counts() {
    echo "Comparing resource counts..."

    local GREEN='\033[0;32m'
    local RED='\033[0;31m'
    local NO_COLOR='\033[0m'

    for NS in $NAMESPACES; do
        for RESOURCE in "${RESOURCES[@]}"; do
            # 计算环境中的资源数量
            ENV_COUNT=$(kubectl get "$RESOURCE" -n "$NS" --no-headers 2>/dev/null | wc -l)

            # 计算YAML文件中的资源数量
            FILE_COUNT=$(find "$PROJECT_ID-$(date +%Y%m%d)/$CLUSTER_NAME/$NS/$RESOURCE" -name "*.yaml" 2>/dev/null | wc -l)

            # 输出结果
            if [ "$ENV_COUNT" -eq "$FILE_COUNT" ]; then
                echo -e "Namespace: $NS, $RESOURCE: ${GREEN}$ENV_COUNT MATCH${NO_COLOR}"
            else
                echo -e "Namespace: $NS, $RESOURCE: ${RED}$ENV_COUNT MISMATCH (Files: $FILE_COUNT)${NO_COLOR}"
            fi
        done
    done
}

# 主程序
NAMESPACES=$(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}')
RESOURCES=("deployments" "services" "configmaps" "secrets")
compare_resource_counts
zking2000 commented 3 months ago

好的,我来帮您修改这段代码,去掉并行执行的特性。以下是去除并行属性后的修改版本:

function export_resources() {
    echo "Exporting GKE resources..."
    for NS in $NAMESPACES; do
        if [[ "$NS" == "kube-"* ]]; then
            continue
        fi

        for RESOURCE in "${RESOURCES[@]}"; do
            RESOURCE_NAMES=$(kubectl get "$RESOURCE" -n "$NS" -o jsonpath='{.items[*].metadata.name}')
            if [ -z "$RESOURCE_NAMES" ]; then
                echo "--- No $RESOURCE found in namespace $NS. ---"
            else
                for RESOURCE_NAME in $RESOURCE_NAMES; do
                    kubectl get "$RESOURCE" "$RESOURCE_NAME" -n "$NS" -o yaml > "$BACKUP_DIR/$CLUSTER_NAME/$NS/$RESOURCE/$RESOURCE_NAME.yaml"
                done
            fi
        done
    done
}

这个修改后的版本有以下变化:

  1. 移除了 job_count 相关的代码,因为我们不再需要跟踪并行作业数量。

  2. 删除了子shell (...) 和后台执行 & 的用法,使所有操作按顺序执行。

  3. 去掉了 MAX_JOBSTIMEOUT 相关的逻辑,因为不再需要控制并行任务数和超时。

  4. 移除了 wait 命令,因为所有操作都是同步执行的。

  5. 删除了超时和进程终止相关的代码。

  6. export https_proxy=http://$PROXY:3128 && 部分被移除。如果需要代理,您可以在脚本开始处设置环境变量。

这个版本将按顺序处理每个命名空间和资源,一次处理一个。虽然执行时间可能会增加,但代码结构更简单,更容易理解和维护。如果您的环境中资源数量不是特别多,这个版本也可能足够满足需求。

如果您需要进行任何进一步的调整或有任何问题,请随时告诉我。​​​​​​​​​​​​​​​​