• 【树莓派不吃灰】命令篇① curl命令


    在这里插入图片描述

    • ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
    • ❤️ 本篇创建记录 2022-11-14 ❤️
    • ❤️ 本篇更新记录 2022-11-14 ❤️
    • 🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言 📝
    • 🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
    • 🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志🔥

    1. 前言

    最近玩树莓派,经常看到这个命令,所以有必要还是要学习一下。

    curl 是常用的命令行工具,用来请求 Web 服务器。

    • curl是一个非常实用的、用来与服务器之间传输数据的工具;
    • 支持的协议包括 (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP)
    • curl设计为无用户交互下完成工作;
    • curl提供了一大堆非常有用的功能,包括代理访问、用户认证、ftp上传下载、HTTP POST、SSL连接、cookie支持、断点续传…。

    在这里插入图片描述

    2. curl命令常用参数

    Linux上遇事不决就help命令。

    pi@raspberrypi:~ $ curl --help all
    Usage: curl [options...] <url>
         --abstract-unix-socket <path> Connect via abstract Unix domain socket
         --alt-svc <file name> Enable alt-svc with this cache file
         --anyauth       Pick any authentication method
     -a, --append        Append to target file when uploading
         --basic         Use HTTP Basic Authentication
         --cacert <file> CA certificate to verify peer against
         --capath <dir>  CA directory to verify peer against
     -E, --cert <certificate[:password]> Client certificate file and password
         --cert-status   Verify the status of the server certificate
         --cert-type <type> Certificate type (DER/PEM/ENG)
         --ciphers <list of ciphers> SSL ciphers to use
         --compressed    Request compressed response
         --compressed-ssh Enable SSH compression
     -K, --config <file> Read config from a file
         --connect-timeout <seconds> Maximum time allowed for connection
         --connect-to <HOST1:PORT1:HOST2:PORT2> Connect to host
     -C, --continue-at <offset> Resumed transfer offset
     -b, --cookie <data|filename> Send cookies from string/file
     -c, --cookie-jar <filename> Write cookies to <filename> after operation
         --create-dirs   Create necessary local directory hierarchy
         --crlf          Convert LF to CRLF in upload
         --crlfile <file> Get a CRL list in PEM format from the given file
         --curves <algorithm list> (EC) TLS key exchange algorithm(s) to request
     -d, --data <data>   HTTP POST data
         --data-ascii <data> HTTP POST ASCII data
         --data-binary <data> HTTP POST binary data
         --data-raw <data> HTTP POST data, '@' allowed
         --data-urlencode <data> HTTP POST data url encoded
         --delegation <LEVEL> GSS-API delegation permission
         --digest        Use HTTP Digest Authentication
     -q, --disable       Disable .curlrc
         --disable-eprt  Inhibit using EPRT or LPRT
         --disable-epsv  Inhibit using EPSV
         --disallow-username-in-url Disallow username in url
         --dns-interface <interface> Interface to use for DNS requests
         --dns-ipv4-addr <address> IPv4 address to use for DNS requests
         --dns-ipv6-addr <address> IPv6 address to use for DNS requests
         --dns-servers <addresses> DNS server addrs to use
         --doh-url <URL> Resolve host names over DOH
     -D, --dump-header <filename> Write the received headers to <filename>
         --egd-file <file> EGD socket path for random data
         --engine <name> Crypto engine to use
         --etag-compare <file> Pass an ETag from a file as a custom header
         --etag-save <file> Parse ETag from a request and save it to a file
         --expect100-timeout <seconds> How long to wait for 100-continue
     -f, --fail          Fail silently (no output at all) on HTTP errors
         --fail-early    Fail on first transfer error, do not continue
         --false-start   Enable TLS False Start
     -F, --form <name=content> Specify multipart MIME data
         --form-string <name=string> Specify multipart MIME data
         --ftp-account <data> Account data string
         --ftp-alternative-to-user <command> String to replace USER [name]
         --ftp-create-dirs Create the remote dirs if not present
         --ftp-method <method> Control CWD usage
         --ftp-pasv      Use PASV/EPSV instead of PORT
     -P, --ftp-port <address> Use PORT instead of PASV
         --ftp-pret      Send PRET before PASV
         --ftp-skip-pasv-ip Skip the IP address for PASV
         --ftp-ssl-ccc   Send CCC after authenticating
         --ftp-ssl-ccc-mode <active/passive> Set CCC mode
         --ftp-ssl-control Require SSL/TLS for FTP login, clear for transfer
     -G, --get           Put the post data in the URL and use GET
     -g, --globoff       Disable URL sequences and ranges using {} and []
         --happy-eyeballs-timeout-ms <milliseconds> Time for IPv6 before trying IPv4
         --haproxy-protocol Send HAProxy PROXY protocol v1 header
     -I, --head          Show document info only
     -H, --header <header/@file> Pass custom header(s) to server
     -h, --help <category> Get help for commands
         --hostpubmd5 <md5> Acceptable MD5 hash of the host public key
         --hsts <file name> Enable HSTS with this cache file
         --http0.9       Allow HTTP 0.9 responses
     -0, --http1.0       Use HTTP 1.0
         --http1.1       Use HTTP 1.1
         --http2         Use HTTP 2
         --http2-prior-knowledge Use HTTP 2 without HTTP/1.1 Upgrade
         --http3         Use HTTP v3
         --ignore-content-length Ignore the size of the remote resource
     -i, --include       Include protocol response headers in the output
     -k, --insecure      Allow insecure server connections when using SSL
         --interface <name> Use network INTERFACE (or address)
     -4, --ipv4          Resolve names to IPv4 addresses
     -6, --ipv6          Resolve names to IPv6 addresses
     -j, --junk-session-cookies Ignore session cookies read from file
         --keepalive-time <seconds> Interval time for keepalive probes
         --key <key>     Private key file name
         --key-type <type> Private key file type (DER/PEM/ENG)
         --krb <level>   Enable Kerberos with security <level>
         --libcurl <file> Dump libcurl equivalent code of this command line
         --limit-rate <speed> Limit transfer speed to RATE
     -l, --list-only     List only mode
         --local-port <num/range> Force use of RANGE for local port numbers
     -L, --location      Follow redirects
         --location-trusted Like --location, and send auth to other hosts
         --login-options <options> Server login options
         --mail-auth <address> Originator address of the original email
         --mail-from <address> Mail from this address
         --mail-rcpt <address> Mail to this address
         --mail-rcpt-allowfails Allow RCPT TO command to fail for some recipients
     -M, --manual        Display the full manual
         --max-filesize <bytes> Maximum file size to download
         --max-redirs <num> Maximum number of redirects allowed
     -m, --max-time <seconds> Maximum time allowed for the transfer
         --metalink      Process given URLs as metalink XML file
         --negotiate     Use HTTP Negotiate (SPNEGO) authentication
     -n, --netrc         Must read .netrc for user name and password
         --netrc-file <filename> Specify FILE for netrc
         --netrc-optional Use either .netrc or URL
     -:, --next          Make next URL use its separate set of options
         --no-alpn       Disable the ALPN TLS extension
     -N, --no-buffer     Disable buffering of the output stream
         --no-keepalive  Disable TCP keepalive on the connection
         --no-npn        Disable the NPN TLS extension
         --no-progress-meter Do not show the progress meter
         --no-sessionid  Disable SSL session-ID reusing
         --noproxy <no-proxy-list> List of hosts which do not use proxy
         --ntlm          Use HTTP NTLM authentication
         --ntlm-wb       Use HTTP NTLM authentication with winbind
         --oauth2-bearer <token> OAuth 2 Bearer Token
     -o, --output <file> Write to file instead of stdout
         --output-dir <dir> Directory to save files in
     -Z, --parallel      Perform transfers in parallel
         --parallel-immediate Do not wait for multiplexing (with --parallel)
         --parallel-max  Maximum concurrency for parallel transfers
         --pass <phrase> Pass phrase for the private key
         --path-as-is    Do not squash .. sequences in URL path
         --pinnedpubkey <hashes> FILE/HASHES Public key to verify peer against
         --post301       Do not switch to GET after following a 301
         --post302       Do not switch to GET after following a 302
         --post303       Do not switch to GET after following a 303
         --preproxy [protocol://]host[:port] Use this proxy first
     -#, --progress-bar  Display transfer progress as a bar
         --proto <protocols> Enable/disable PROTOCOLS
         --proto-default <protocol> Use PROTOCOL for any URL missing a scheme
         --proto-redir <protocols> Enable/disable PROTOCOLS on redirect
     -x, --proxy [protocol://]host[:port] Use this proxy
         --proxy-anyauth Pick any proxy authentication method
         --proxy-basic   Use Basic authentication on the proxy
         --proxy-cacert <file> CA certificate to verify peer against for proxy
         --proxy-capath <dir> CA directory to verify peer against for proxy
         --proxy-cert <cert[:passwd]> Set client certificate for proxy
         --proxy-cert-type <type> Client certificate type for HTTPS proxy
         --proxy-ciphers <list> SSL ciphers to use for proxy
         --proxy-crlfile <file> Set a CRL list for proxy
         --proxy-digest  Use Digest authentication on the proxy
         --proxy-header <header/@file> Pass custom header(s) to proxy
         --proxy-insecure Do HTTPS proxy connections without verifying the proxy
         --proxy-key <key> Private key for HTTPS proxy
         --proxy-key-type <type> Private key file type for proxy
         --proxy-negotiate Use HTTP Negotiate (SPNEGO) authentication on the proxy
         --proxy-ntlm    Use NTLM authentication on the proxy
         --proxy-pass <phrase> Pass phrase for the private key for HTTPS proxy
         --proxy-pinnedpubkey <hashes> FILE/HASHES public key to verify proxy with
         --proxy-service-name <name> SPNEGO proxy service name
         --proxy-ssl-allow-beast Allow security flaw for interop for HTTPS proxy
         --proxy-tls13-ciphers <ciphersuite list> TLS 1.3 proxy cipher suites
         --proxy-tlsauthtype <type> TLS authentication type for HTTPS proxy
         --proxy-tlspassword <string> TLS password for HTTPS proxy
         --proxy-tlsuser <name> TLS username for HTTPS proxy
         --proxy-tlsv1   Use TLSv1 for HTTPS proxy
     -U, --proxy-user <user:password> Proxy user and password
         --proxy1.0 <host[:port]> Use HTTP/1.0 proxy on given port
     -p, --proxytunnel   Operate through an HTTP proxy tunnel (using CONNECT)
         --pubkey <key>  SSH Public key file name
     -Q, --quote         Send command(s) to server before transfer
         --random-file <file> File for reading random data from
     -r, --range <range> Retrieve only the bytes within RANGE
         --raw           Do HTTP "raw"; no transfer decoding
     -e, --referer <URL> Referrer URL
     -J, --remote-header-name Use the header-provided filename
     -O, --remote-name   Write output to a file named as the remote file
         --remote-name-all Use the remote file name for all URLs
     -R, --remote-time   Set the remote file's time on the local output
     -X, --request <command> Specify request command to use
         --request-target Specify the target for this request
         --resolve <host:port:addr[,addr]...> Resolve the host+port to this address
         --retry <num>   Retry request if transient problems occur
         --retry-all-errors Retry all errors (use with --retry)
         --retry-connrefused Retry on connection refused (use with --retry)
         --retry-delay <seconds> Wait time between retries
         --retry-max-time <seconds> Retry only within this period
         --sasl-authzid <identity> Identity for SASL PLAIN authentication
         --sasl-ir       Enable initial response in SASL authentication
         --service-name <name> SPNEGO service name
     -S, --show-error    Show error even when -s is used
     -s, --silent        Silent mode
         --socks4 <host[:port]> SOCKS4 proxy on given host + port
         --socks4a <host[:port]> SOCKS4a proxy on given host + port
         --socks5 <host[:port]> SOCKS5 proxy on given host + port
         --socks5-basic  Enable username/password auth for SOCKS5 proxies
         --socks5-gssapi Enable GSS-API auth for SOCKS5 proxies
         --socks5-gssapi-nec Compatibility with NEC SOCKS5 server
         --socks5-gssapi-service <name> SOCKS5 proxy service name for GSS-API
         --socks5-hostname <host[:port]> SOCKS5 proxy, pass host name to proxy
     -Y, --speed-limit <speed> Stop transfers slower than this
     -y, --speed-time <seconds> Trigger 'speed-limit' abort after this time
         --ssl           Try SSL/TLS
         --ssl-allow-beast Allow security flaw to improve interop
         --ssl-no-revoke Disable cert revocation checks (Schannel)
         --ssl-reqd      Require SSL/TLS
         --ssl-revoke-best-effort Ignore missing/offline cert CRL dist points
     -2, --sslv2         Use SSLv2
     -3, --sslv3         Use SSLv3
         --stderr        Where to redirect stderr
         --styled-output Enable styled output for HTTP headers
         --suppress-connect-headers Suppress proxy CONNECT response headers
         --tcp-fastopen  Use TCP Fast Open
         --tcp-nodelay   Use the TCP_NODELAY option
     -t, --telnet-option <opt=val> Set telnet option
         --tftp-blksize <value> Set TFTP BLKSIZE option
         --tftp-no-options Do not send any TFTP options
     -z, --time-cond <time> Transfer based on a time condition
         --tls-max <VERSION> Set maximum allowed TLS version
         --tls13-ciphers <ciphersuite list> TLS 1.3 cipher suites to use
         --tlsauthtype <type> TLS authentication type
         --tlspassword   TLS password
         --tlsuser <name> TLS user name
     -1, --tlsv1         Use TLSv1.0 or greater
         --tlsv1.0       Use TLSv1.0 or greater
         --tlsv1.1       Use TLSv1.1 or greater
         --tlsv1.2       Use TLSv1.2 or greater
         --tlsv1.3       Use TLSv1.3 or greater
         --tr-encoding   Request compressed transfer encoding
         --trace <file>  Write a debug trace to FILE
         --trace-ascii <file> Like --trace, but without hex output
         --trace-time    Add time stamps to trace/verbose output
         --unix-socket <path> Connect through this Unix domain socket
     -T, --upload-file <file> Transfer local FILE to destination
         --url <url>     URL to work with
     -B, --use-ascii     Use ASCII/text transfer
     -u, --user <user:password> Server user and password
     -A, --user-agent <name> Send User-Agent <name> to server
     -v, --verbose       Make the operation more talkative
     -V, --version       Show version number and quit
     -w, --write-out <format> Use output FORMAT after completion
         --xattr         Store metadata in extended file attributes
    pi@raspberrypi:~ $ 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239

    一句话,真的非常多参数。

    参考资料:

    2.1 不带有任何参数时,curl 就是发出 GET 请求

    pi@raspberrypi:~ $ curl www.baidu.com
    <!DOCTYPE html>
    <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css>百度一下,你就知道  

    关于百度 About Baidu

    ©2017 Baidu 使用百度前必读  意见反馈 京ICP证030173号 

    • 1
    • 2
    • 3

    这里直接访问百度,获得了百度的html内容。

    2.2 -i参数打印出服务器回应的 HTTP 标头。

    pi@raspberrypi:~ $ curl -i www.baidu.com
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
    Connection: keep-alive
    Content-Length: 2381
    Content-Type: text/html
    Date: Mon, 14 Nov 2022 14:07:40 GMT
    Etag: "588604d8-94d"
    Last-Modified: Mon, 23 Jan 2017 13:27:52 GMT
    Pragma: no-cache
    Server: bfe/1.0.8.18
    Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.3 -I参数向服务器发出 HEAD 请求,然会将服务器返回的 HTTP 标头打印出来。

    这里只是发起head请求

    pi@raspberrypi:~ $ curl -I www.baidu.com
    HTTP/1.1 200 OK
    Accept-Ranges: bytes
    Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
    Connection: keep-alive
    Content-Length: 277
    Content-Type: text/html
    Date: Mon, 14 Nov 2022 14:08:21 GMT
    Etag: "575e1f72-115"
    Last-Modified: Mon, 13 Jun 2016 02:50:26 GMT
    Pragma: no-cache
    Server: bfe/1.0.8.18
    
    pi@raspberrypi:~ $ 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.4 -o参数将服务器的回应保存成文件,等同于wget命令

    pi@raspberrypi:~ $ curl -o baidu.html www.baidu.com
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  2381  100  2381    0     0  62657      0 --:--:-- --:--:-- --:--:-- 62657
    pi@raspberrypi:~ $ ls -al
    total 132
    drwxr-xr-x 21 pi   pi    4096 Nov 14 14:11 .
    drwxr-xr-x  3 root root  4096 Sep 22 02:02 ..
    -rw-r--r--  1 pi   pi       0 Nov 10 12:29 100
    -rw-r--r--  1 pi   pi    2381 Nov 14 14:11 baidu.html
    -rw-------  1 pi   pi   16304 Nov 14 05:42 .bash_history
    -rw-r--r--  1 pi   pi     220 Sep 22 01:05 .bash_logout
    -rw-r--r--  1 pi   pi    3523 Sep 22 01:05 .bashrc
    drwxr-xr-x  2 pi   pi    4096 Sep 22 01:14 Bookshelf
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.5 -O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名

    pi@raspberrypi:~ $ curl -O https://www.baidu.com/index.html
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  2443  100  2443    0     0  23718      0 --:--:-- --:--:-- --:--:-- 23950
    pi@raspberrypi:~ $ ls -al
    total 132
    drwxr-xr-x 21 pi   pi    4096 Nov 14 14:13 .
    drwxr-xr-x  3 root root  4096 Sep 22 02:02 ..
    -rw-r--r--  1 pi   pi       0 Nov 10 12:29 100
    -rw-------  1 pi   pi   16304 Nov 14 05:42 .bash_history
    -rw-r--r--  1 pi   pi     220 Sep 22 01:05 .bash_logout
    -rw-r--r--  1 pi   pi    3523 Sep 22 01:05 .bashrc
    drwxr-xr-x  2 pi   pi    4096 Sep 22 01:14 Bookshelf
    drwxr-xr-x  5 pi   pi    4096 Nov  5 01:14 .cache
    drwx------ 10 pi   pi    4096 Nov  8 14:24 .config
    drwx------  2 pi   pi    4096 Nov  5 01:11 .cups
    drwxr-xr-x  2 pi   pi    4096 Sep 22 02:02 Desktop
    drwxr-xr-x  2 pi   pi    4096 Sep 22 02:02 Documents
    drwxr-xr-x  2 pi   pi    4096 Sep 22 02:02 Downloads
    drwxr-xr-x  2 pi   pi    4096 Nov  8 15:44 frp_0.45.0_linux_arm
    drwxr-xr-x  7 root root  4096 Nov 13 04:46 homeassistant
    -rw-r--r--  1 pi   pi    2443 Nov 14 14:13 index.html
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3. curl命令参数详解

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    vue3 + antd 图片上传 (精简篇)cv即可
    目标检测算法——YOLOv5/YOLOv7改进结合新神经网络算子Involution(CVPR 2021)
    局域网组建教程
    第4讲:Python常用的几种基本运算符的概念以及使用
    【无标题】
    网课题库接口API—小白专用
    自己实现SpringBoot三方Starer依赖封装(自动装配自定义实现)
    1. 云计算简介
    Word设置封面无页码,摘要罗马数字页码,正文数字页码
    Java#31(不可变集合,Stream流和方法引用)
  • 原文地址:https://blog.csdn.net/weixin_44614230/article/details/127855777