curl 命令详解#

curl(Client URL)是 Linux 系统中用于传输数据的命令行工具,支持多种协议(HTTP、HTTPS、FTP、FTPES、SCP、SFTP、TFTP、LDAP、LDAPS、DICT、TELNET、FILE、IMAP、POP3、SMTP、RTMP、RTSP 等),是开发和运维中最常用的网络工具之一。

入门#

基本用法#

# 获取网页内容
curl https://example.com

# 保存网页到文件
curl -o output.html https://example.com

# 使用远程文件名保存
curl -O https://example.com/file.zip

# 显示响应头
curl -I https://example.com

# 显示详细信息
curl -v https://example.com

常用选项#

选项说明
-o指定输出文件名
-O使用远程文件名保存
-I只显示响应头
-v显示详细输出
-s静默模式
-L跟随重定向
-u指定用户名和密码
-d发送 POST 数据
-H添加请求头
-X指定请求方法

基本示例#

# 获取网页内容
curl https://www.example.com

# 下载文件
curl -O https://example.com/file.zip

# 查看响应头
curl -I https://example.com

# 跟随重定向
curl -L https://example.com

# 静默模式
curl -s https://example.com

中级#

HTTP 请求方法#

# GET 请求(默认)
curl https://api.example.com/users

# POST 请求
curl -X POST https://api.example.com/users -d "name=John&age=30"

# PUT 请求
curl -X PUT https://api.example.com/users/1 -d "name=John&age=31"

# DELETE 请求
curl -X DELETE https://api.example.com/users/1

# PATCH 请求
curl -X PATCH https://api.example.com/users/1 -d "age=32"

请求头和认证#

# 添加请求头
curl -H "Content-Type: application/json" https://api.example.com/users

# 添加多个请求头
curl -H "Content-Type: application/json" -H "Authorization: Bearer token" https://api.example.com/users

# 基本认证
curl -u username:password https://api.example.com/users

# Bearer Token 认证
curl -H "Authorization: Bearer your_token" https://api.example.com/users

# API Key 认证
curl -H "X-API-Key: your_api_key" https://api.example.com/users

数据传输#

# 发送表单数据
curl -d "name=John&age=30" https://api.example.com/users

# 发送 JSON 数据
curl -H "Content-Type: application/json" -d '{"name":"John","age":30}' https://api.example.com/users

# 从文件发送数据
curl -d @data.json https://api.example.com/users

# 上传文件
curl -F "file=@/path/to/file.txt" https://api.example.com/upload

# 上传多个文件
curl -F "file1=@/path/to/file1.txt" -F "file2=@/path/to/file2.txt" https://api.example.com/upload

高级#

高级选项#

# 设置超时时间
curl --max-time 30 https://example.com

# 设置连接超时
curl --connect-timeout 10 https://example.com

# 限制下载速度
curl --limit-rate 100k https://example.com/file.zip

# 断点续传
curl -C - -O https://example.com/file.zip

# 使用代理
curl -x http://proxy.example.com:8080 https://example.com

# 使用 SOCKS 代理
curl --socks5 127.0.0.1:1080 https://example.com

# 忽略 SSL 证书验证
curl -k https://example.com

# 使用客户端证书
curl --cert client.crt --key client.key https://example.com
# 保存 Cookie
curl -c cookies.txt https://example.com/login

# 使用 Cookie
curl -b cookies.txt https://example.com/profile

# 发送特定 Cookie
curl -b "session_id=abc123" https://example.com/profile

# 保存和发送 Cookie
curl -b cookies.txt -c cookies.txt https://example.com/profile

# 删除 Cookie
curl -b "session_id=; expires=Thu, 01 Jan 1970 00:00:00 GMT" https://example.com/logout

调试和日志#

# 显示详细调试信息
curl -v https://example.com

# 显示请求和响应头
curl -i https://example.com

# 显示请求头
curl --trace-ascii /dev/stderr https://example.com

# 保存调试信息到文件
curl --trace debug.log https://example.com

# 显示时间统计
curl -w "@format.txt" https://example.com

# format.txt 示例:
# time_namelookup:  %{time_namelookup}\n
# time_connect:     %{time_connect}\n
# time_appconnect:  %{time_appconnect}\n
# time_pretransfer: %{time_pretransfer}\n
# time_starttransfer: %{time_starttransfer}\n
# time_total:       %{time_total}\n

大师#

API 测试和调试#

#!/bin/bash
# API 测试脚本

BASE_URL="https://api.example.com"
TOKEN="your_api_token"

# 测试 GET 请求
test_get() {
    local endpoint=$1
    echo "Testing GET: $endpoint"
    curl -X GET "$BASE_URL$endpoint" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -w "\nHTTP Status: %{http_code}\n" \
        -s
    echo ""
}

# 测试 POST 请求
test_post() {
    local endpoint=$1
    local data=$2
    echo "Testing POST: $endpoint"
    curl -X POST "$BASE_URL$endpoint" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -d "$data" \
        -w "\nHTTP Status: %{http_code}\n" \
        -s
    echo ""
}

# 测试 PUT 请求
test_put() {
    local endpoint=$1
    local data=$2
    echo "Testing PUT: $endpoint"
    curl -X PUT "$BASE_URL$endpoint" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -d "$data" \
        -w "\nHTTP Status: %{http_code}\n" \
        -s
    echo ""
}

# 测试 DELETE 请求
test_delete() {
    local endpoint=$1
    echo "Testing DELETE: $endpoint"
    curl -X DELETE "$BASE_URL$endpoint" \
        -H "Authorization: Bearer $TOKEN" \
        -H "Content-Type: application/json" \
        -w "\nHTTP Status: %{http_code}\n" \
        -s
    echo ""
}

# 批量测试
batch_test() {
    test_get "/users"
    test_post "/users" '{"name":"John","age":30}'
    test_get "/users/1"
    test_put "/users/1" '{"name":"John","age":31}'
    test_delete "/users/1"
}

batch_test

网站监控#

#!/bin/bash
# 网站监控脚本

WEBSITES=("https://example.com" "https://api.example.com" "https://blog.example.com")
LOG_FILE="website_monitor.log"
ALERT_EMAIL="admin@example.com"

# 检查网站状态
check_website() {
    local url=$1
    local response_time
    local http_code
    
    response_time=$(curl -o /dev/null -s -w '%{time_total}' "$url")
    http_code=$(curl -o /dev/null -s -w '%{http_code}' "$url")
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $url - HTTP $http_code - ${response_time}s" >> $LOG_FILE
    
    if [ $http_code -ne 200 ]; then
        echo "ALERT: $url returned HTTP $http_code" | mail -s "Website Alert" $ALERT_EMAIL
    fi
    
    if (( $(echo "$response_time > 3.0" | bc -l) )); then
        echo "WARNING: $url response time is ${response_time}s" | mail -s "Performance Warning" $ALERT_EMAIL
    fi
}

# 主监控循环
main() {
    while true; do
        for WEBSITE in "${WEBSITES[@]}"; do
            check_website "$WEBSITE"
        done
        sleep 300
    done
}

main

批量下载#

#!/bin/bash
# 批量下载脚本

BASE_URL="https://example.com/files/"
OUTPUT_DIR="downloads"
LOG_FILE="download.log"

mkdir -p $OUTPUT_DIR

# 从文件列表下载
download_from_list() {
    local list_file=$1
    
    while IFS= read -r filename; do
        echo "Downloading: $filename"
        curl -O "$BASE_URL$filename" 2>> $LOG_FILE
    done < "$list_file"
}

# 按模式下载
download_by_pattern() {
    local pattern=$1
    local start=$2
    local end=$3
    
    for ((i=start; i<=end; i++)); do
        local filename=$(printf "$pattern" $i)
        echo "Downloading: $filename"
        curl -O "$BASE_URL$filename" 2>> $LOG_FILE
    done
}

# 并行下载
parallel_download() {
    local urls=("$@")
    
    for url in "${urls[@]}"; do
        curl -O "$url" &
    done
    
    wait
}

# 断点续传下载
resumable_download() {
    local url=$1
    local output=$2
    
    while true; do
        curl -C - -o "$output" "$url"
        
        if [ $? -eq 0 ]; then
            echo "Download completed: $output"
            break
        else
            echo "Download interrupted, retrying..."
            sleep 5
        fi
    done
}

# 主函数
main() {
    case "$1" in
        list)
            download_from_list "$2"
            ;;
        pattern)
            download_by_pattern "$2" "$3" "$4"
            ;;
        parallel)
            parallel_download "${@:2}"
            ;;
        resume)
            resumable_download "$2" "$3"
            ;;
        *)
            echo "Usage: $0 {list|pattern|parallel|resume}"
            exit 1
            ;;
    esac
}

main "$@"

无敌#

企业级 API 测试框架#

#!/bin/bash
# 企业级 API 测试框架

CONFIG_FILE="api_test_config.conf"
TEST_RESULTS_DIR="test_results"
REPORT_FILE="test_report_$(date +%Y%m%d_%H%M%S).html"

mkdir -p $TEST_RESULTS_DIR

# 加载配置
load_config() {
    if [ -f "$CONFIG_FILE" ]; then
        source $CONFIG_FILE
    else
        echo "Config file not found: $CONFIG_FILE"
        exit 1
    fi
}

# 执行 API 测试
execute_test() {
    local test_name=$1
    local method=$2
    local endpoint=$3
    local expected_code=$4
    local data=$5
    
    local full_url="${BASE_URL}${endpoint}"
    local response_file="$TEST_RESULTS_DIR/${test_name}_response.json"
    local start_time end_time duration
    
    echo "Running test: $test_name"
    
    start_time=$(date +%s.%N)
    
    if [ -n "$data" ]; then
        http_code=$(curl -X $method "$full_url" \
            -H "Authorization: Bearer $TOKEN" \
            -H "Content-Type: application/json" \
            -d "$data" \
            -o "$response_file" \
            -w "%{http_code}" \
            -s)
    else
        http_code=$(curl -X $method "$full_url" \
            -H "Authorization: Bearer $TOKEN" \
            -H "Content-Type: application/json" \
            -o "$response_file" \
            -w "%{http_code}" \
            -s)
    fi
    
    end_time=$(date +%s.%N)
    duration=$(echo "$end_time - $start_time" | bc)
    
    if [ "$http_code" -eq "$expected_code" ]; then
        echo "✓ PASS: $test_name (HTTP $http_code, ${duration}s)"
        return 0
    else
        echo "✗ FAIL: $test_name (Expected: $expected_code, Got: $http_code, ${duration}s)"
        return 1
    fi
}

# 执行测试套件
run_test_suite() {
    local total_tests=0
    local passed_tests=0
    local failed_tests=0
    
    echo "=== API Test Suite ==="
    echo ""
    
    # 测试用例
    execute_test "get_users" "GET" "/users" 200
    total_tests=$((total_tests + 1))
    if [ $? -eq 0 ]; then passed_tests=$((passed_tests + 1)); else failed_tests=$((failed_tests + 1)); fi
    
    execute_test "create_user" "POST" "/users" 201 '{"name":"Test User","age":25}'
    total_tests=$((total_tests + 1))
    if [ $? -eq 0 ]; then passed_tests=$((passed_tests + 1)); else failed_tests=$((failed_tests + 1)); fi
    
    execute_test "get_user" "GET" "/users/1" 200
    total_tests=$((total_tests + 1))
    if [ $? -eq 0 ]; then passed_tests=$((passed_tests + 1)); else failed_tests=$((failed_tests + 1)); fi
    
    execute_test "update_user" "PUT" "/users/1" 200 '{"name":"Updated User","age":26}'
    total_tests=$((total_tests + 1))
    if [ $? -eq 0 ]; then passed_tests=$((passed_tests + 1)); else failed_tests=$((failed_tests + 1)); fi
    
    execute_test "delete_user" "DELETE" "/users/1" 204
    total_tests=$((total_tests + 1))
    if [ $? -eq 0 ]; then passed_tests=$((passed_tests + 1)); else failed_tests=$((failed_tests + 1)); fi
    
    echo ""
    echo "=== Test Summary ==="
    echo "Total Tests: $total_tests"
    echo "Passed: $passed_tests"
    echo "Failed: $failed_tests"
    echo "Success Rate: $(echo "scale=2; $passed_tests * 100 / $total_tests" | bc)%"
}

# 生成 HTML 报告
generate_html_report() {
    cat > $REPORT_FILE << EOF
<!DOCTYPE html>
<html>
<head>
    <title>API Test Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .pass { color: green; }
        .fail { color: red; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #4CAF50; color: white; }
    </style>
</head>
<body>
    <h1>API Test Report</h1>
    <p>Generated: $(date)</p>
    
    <h2>Test Results</h2>
    <table>
        <tr>
            <th>Test Name</th>
            <th>Status</th>
            <th>Response Time</th>
        </tr>
EOF

    # 添加测试结果
    ls $TEST_RESULTS_DIR/*.json | while read response_file; do
        local test_name=$(basename $response_file | sed 's/_response.json//')
        local status="PASS"
        local response_time="0.5s"
        
        echo "        <tr>" >> $REPORT_FILE
        echo "            <td>$test_name</td>" >> $REPORT_FILE
        echo "            <td class='$status'>$status</td>" >> $REPORT_FILE
        echo "            <td>$response_time</td>" >> $REPORT_FILE
        echo "        </tr>" >> $REPORT_FILE
    done

    cat >> $REPORT_FILE << EOF
    </table>
</body>
</html>
EOF

    echo "HTML report generated: $REPORT_FILE"
}

# 主函数
main() {
    load_config
    run_test_suite
    generate_html_report
}

main

性能测试工具#

#!/bin/bash
# API 性能测试工具

API_URL="https://api.example.com/endpoint"
CONCURRENT_REQUESTS=10
TOTAL_REQUESTS=100
OUTPUT_FILE="performance_results.csv"

# 单次请求测试
single_request() {
    local url=$1
    
    local start_time=$(date +%s.%N)
    local http_code=$(curl -o /dev/null -s -w "%{http_code}" "$url")
    local end_time=$(date +%s.%N)
    local duration=$(echo "$end_time - $start_time" | bc)
    
    echo "$http_code,$duration"
}

# 并发请求测试
concurrent_test() {
    local url=$1
    local concurrent=$2
    local total=$3
    
    echo "Running concurrent test: $concurrent concurrent requests, $total total requests"
    
    local completed=0
    
    while [ $completed -lt $total ]; do
        local batch=$((concurrent))
        if [ $((completed + batch)) -gt $total ]; then
            batch=$((total - completed))
        fi
        
        for ((i=0; i<batch; i++)); do
            single_request "$url" >> $OUTPUT_FILE &
        done
        
        wait
        completed=$((completed + batch))
        
        echo "Progress: $completed/$total requests completed"
    done
}

# 分析结果
analyze_results() {
    echo "=== Performance Analysis ==="
    
    local total_requests=$(wc -l < $OUTPUT_FILE)
    local successful_requests=$(awk -F, '$1 == 200' $OUTPUT_FILE | wc -l)
    local failed_requests=$((total_requests - successful_requests))
    
    local avg_response_time=$(awk -F, '{sum+=$2; count++} END {print sum/count}' $OUTPUT_FILE)
    local min_response_time=$(awk -F, 'NR==1 || $2 < min {min=$2} END {print min}' $OUTPUT_FILE)
    local max_response_time=$(awk -F, 'NR==1 || $2 > max {max=$2} END {print max}' $OUTPUT_FILE)
    
    local requests_per_second=$(echo "scale=2; $total_requests / $avg_response_time" | bc)
    
    echo "Total Requests: $total_requests"
    echo "Successful: $successful_requests"
    echo "Failed: $failed_requests"
    echo "Success Rate: $(echo "scale=2; $successful_requests * 100 / $total_requests" | bc)%"
    echo ""
    echo "Response Time:"
    echo "  Average: ${avg_response_time}s"
    echo "  Min: ${min_response_time}s"
    echo "  Max: ${max_response_time}s"
    echo ""
    echo "Throughput: ${requests_per_second} requests/second"
}

# 主函数
main() {
    echo "timestamp,http_code,response_time" > $OUTPUT_FILE
    
    concurrent_test "$API_URL" $CONCURRENT_REQUESTS $TOTAL_REQUESTS
    
    analyze_results
    
    echo "Results saved to: $OUTPUT_FILE"
}

main

自动化部署工具#

#!/bin/bash
# 基于 curl 的自动化部署工具

DEPLOY_CONFIG="deploy.conf"
LOG_FILE="deploy_$(date +%Y%m%d_%H%M%S).log"

# 加载部署配置
load_deploy_config() {
    if [ -f "$DEPLOY_CONFIG" ]; then
        source $DEPLOY_CONFIG
    else
        echo "Deploy config not found: $DEPLOY_CONFIG"
        exit 1
    fi
}

# 健康检查
health_check() {
    local url=$1
    local max_retries=5
    local retry_count=0
    
    echo "Performing health check on $url..."
    
    while [ $retry_count -lt $max_retries ]; do
        http_code=$(curl -o /dev/null -s -w "%{http_code}" "$url")
        
        if [ "$http_code" -eq 200 ]; then
            echo "✓ Health check passed"
            return 0
        fi
        
        echo "✗ Health check failed (HTTP $http_code), retrying..."
        retry_count=$((retry_count + 1))
        sleep 10
    done
    
    echo "✗ Health check failed after $max_retries attempts"
    return 1
}

# 触发部署
trigger_deployment() {
    local api_url=$1
    local payload=$2
    
    echo "Triggering deployment..."
    
    response=$(curl -X POST "$api_url" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $DEPLOY_TOKEN" \
        -d "$payload" \
        -w "\n%{http_code}" \
        -s)
    
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | head -n-1)
    
    if [ "$http_code" -eq 200 ] || [ "$http_code" -eq 201 ]; then
        echo "✓ Deployment triggered successfully"
        echo "Response: $body"
        return 0
    else
        echo "✗ Deployment trigger failed (HTTP $http_code)"
        echo "Response: $body"
        return 1
    fi
}

# 监控部署状态
monitor_deployment() {
    local status_url=$1
    local deployment_id=$2
    
    echo "Monitoring deployment $deployment_id..."
    
    while true; do
        status=$(curl -s "$status_url/$deployment_id" | jq -r '.status')
        
        case "$status" in
            "success")
                echo "✓ Deployment completed successfully"
                return 0
                ;;
            "failed")
                echo "✗ Deployment failed"
                return 1
                ;;
            "in_progress"|"pending")
                echo "Deployment in progress..."
                sleep 10
                ;;
            *)
                echo "Unknown status: $status"
                sleep 10
                ;;
        esac
    done
}

# 回滚部署
rollback_deployment() {
    local api_url=$1
    local deployment_id=$2
    
    echo "Rolling back deployment $deployment_id..."
    
    response=$(curl -X POST "$api_url/$deployment_id/rollback" \
        -H "Authorization: Bearer $DEPLOY_TOKEN" \
        -w "\n%{http_code}" \
        -s)
    
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" -eq 200 ]; then
        echo "✓ Rollback initiated"
        return 0
    else
        echo "✗ Rollback failed"
        return 1
    fi
}

# 主部署流程
main() {
    load_deploy_config
    
    echo "=== Starting Deployment ==="
    echo "Environment: $ENVIRONMENT"
    echo "Version: $VERSION"
    echo ""
    
    # 触发部署
    if trigger_deployment "$DEPLOY_API_URL" "{\"version\":\"$VERSION\",\"environment\":\"$ENVIRONMENT\"}"; then
        deployment_id=$(curl -s "$DEPLOY_API_URL" | jq -r '.deployment_id')
        
        # 监控部署
        if monitor_deployment "$STATUS_API_URL" "$deployment_id"; then
            # 健康检查
            if health_check "$HEALTH_CHECK_URL"; then
                echo "=== Deployment Successful ==="
                exit 0
            else
                echo "=== Health Check Failed ==="
                rollback_deployment "$DEPLOY_API_URL" "$deployment_id"
                exit 1
            fi
        else
            echo "=== Deployment Failed ==="
            rollback_deployment "$DEPLOY_API_URL" "$deployment_id"
            exit 1
        fi
    else
        echo "=== Deployment Trigger Failed ==="
        exit 1
    fi
}

main

最佳实践#

  1. 使用 HTTPS:始终使用 HTTPS 保护数据传输安全
  2. 验证 SSL 证书:不要在生产环境中使用 -k 选项
  3. 设置超时:合理设置连接和数据传输超时时间
  4. 使用用户代理:设置合适的 User-Agent 标识
  5. 处理错误:检查 HTTP 状态码并处理错误情况
  6. 限制速率:避免对服务器造成过大压力
  7. 使用配置文件:对于复杂的请求,使用配置文件管理
  8. 记录日志:记录重要的请求和响应信息

注意事项#

  • curl 支持的协议非常丰富,根据需要选择合适的协议
  • 在处理敏感数据时,注意保护认证信息
  • 大文件下载时使用断点续传功能
  • 并发请求时注意控制并发数量
  • API 测试时注意不要对生产环境造成影响
  • 使用 -v 选项调试时注意保护敏感信息
  • 不同版本的 curl 选项可能有所不同
  • 在自动化脚本中添加适当的错误处理