{"id":9102,"date":"2019-02-03T12:59:58","date_gmt":"2019-02-03T12:59:58","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw92\/?p=9102"},"modified":"2019-03-27T01:45:22","modified_gmt":"2019-03-27T01:45:22","slug":"curl-in-bash-scripts-by-example-linux-hint","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/02\/03\/curl-in-bash-scripts-by-example-linux-hint\/","title":{"rendered":"Curl in Bash Scripts by Example \u2013 Linux Hint"},"content":{"rendered":"<p>If you\u2019ve ever sat in front of a terminal, typed \u2018curl\u2019, pasted the URL of something you want to download, and hit enter, cool! You\u2019re going to be killing it with curl in bash scripts in no time. Here you will learn how to use curl in bash scripts and important tips and tricks for automation.<\/p>\n<p class=\" IL_IC_MIN\">Great! Now what? Before you kill anything in bash it is dire to know where to get help if in trouble. Here is what the man page for curl or curl help command looks like. Copy and paste. Try not to be overwhelmed by appearances. There are a lot of options that you only need later in life. More importantly, it serves as a quick reference to lookup options as you need.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-35917\" src=\"https:\/\/linuxhint.com\/wp-content\/uploads\/2019\/01\/1-45.png\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" srcset=\"https:\/\/linuxhint.com\/wp-content\/uploads\/2019\/01\/1-45.png 560w, https:\/\/linuxhint.com\/wp-content\/uploads\/2019\/01\/1-45-242x300.png 242w\" alt=\"\" width=\"560\" height=\"694\" \/><\/p>\n<p>Here are some commands to get help within your terminal and other browser-friendly\u00a0 resources.<\/p>\n<p>Help commands for curl in bash<\/p>\n<ul>\n<li>man curl<\/li>\n<li>curl \u2013help or curl -h<\/li>\n<li><a href=\"https:\/\/ec.haxx.se\/cmdline.html\">Everything curl; Command line basics<\/a><\/li>\n<\/ul>\n<p>Consult these resources anytime you need. In addition to this piece, they will serve as companions on your journey towards killing it with curl in bash scripts.<\/p>\n<p>Now that getting help and listing command line options is out of the picture, let\u2019s move on to the three ways.<\/p>\n<h3><strong>The three ways to curl in bash by example<\/strong><\/h3>\n<p>You may argue that there are more than three ways to curl in bash. However, for simplicity purposes, let\u2019s just say that there are. Also note that in practice, usage of each way is not mutually exclusive. In fact, you will find that ways may be intertwined depending on the intent of your bash script. Let\u2019s begin.<\/p>\n<h3><strong>The first way: Downloading files<\/strong><\/h3>\n<p>All options aside curl downloads files by default. In bash, we curl to download a file as follows.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\">curl\u00a0<span class=\"co1\">${url}<\/span><br \/>\n<span class=\"co0\"># download file<\/span><\/div>\n<\/div>\n<p>This sends the content of the file we are downloading to standard output; that is, the your screen. If the file is a video or an image don\u2019t be surprised if you hear a few beeps. We need to save to a file. Here\u2019s how it looks.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\">curl\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"sy0\">&gt;<\/span>\u00a0outfile<br \/>\n<span class=\"co0\"># download file saving as outfile<\/span><\/p>\n<p>curl\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"re5\">-o<\/span>\u00a0outfile<br \/>\n<span class=\"co0\"># download file save as option<\/span><\/p>\n<p>curl\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"re5\">-O<\/span><br \/>\n<span class=\"co0\"># download file inherit filename<\/span><\/p>\n<p><span class=\"co0\">## expect file saved as $( basename ${url} )<\/span><\/div>\n<\/div>\n<p>Note that the download file save as option inheriting file name is particularly useful when using URL globbing, which is covered in the bash curl loop section.<\/p>\n<p>Now let\u2019s move on to how to check headers prior to downloading a file with curl in bash.<\/p>\n<h3><strong>The second way: Checking headers<\/strong><\/h3>\n<p>There will come a time when you wish to get information about a file before downloading. To do this, we add the -I option to the curl command as follows.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\">curl\u00a0<span class=\"re5\">-I<\/span>\u00a0<span class=\"co1\">${url}<\/span><br \/>\n<span class=\"co0\"># download headers<\/span><\/div>\n<\/div>\n<p>Note that there are other ways to dump headers from curl requests, which is left for homework.<\/p>\n<p>Here is a quick example to show how the second way works in bash scripts that can be used to serve as a part of a web page health checker.<\/p>\n<h4>Example) bash curl get response code<\/h4>\n<p>Often, we want to get the response code for a curl request in bash. To do this, we would need to first request the headers of a response and then extract the response code. Here is what it would look like.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"re2\">url<\/span>=https:<span class=\"sy0\">\/\/<\/span>temptemp3.github.io<br \/>\n<span class=\"co0\"># just some url<\/span><\/p>\n<p>curl\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"re5\">-I<\/span>\u00a0<span class=\"re5\">-o<\/span>\u00a0headers\u00a0<span class=\"re5\">-s<\/span><br \/>\n<span class=\"co0\"># download file<\/span><\/p>\n<p><span class=\"kw2\">cat<\/span>\u00a0 headers<br \/>\n<span class=\"co0\"># response headers<\/span><br \/>\n<span class=\"co0\">## expect<\/span><br \/>\n<span class=\"co0\">#HTTP\/2 200<\/span><br \/>\n<span class=\"co0\">#server: GitHub.com<\/span><br \/>\n<span class=\"co0\">#content-type: text\/html; charset=utf-8<\/span><br \/>\n<span class=\"co0\">#strict-transport-security: max-age=31557600<\/span><br \/>\n<span class=\"co0\">#last-modified: Thu, 03 May 2018 02:30:03 GMT<\/span><br \/>\n<span class=\"co0\">#etag: &#8220;5aea742b-e12&#8221;<\/span><br \/>\n<span class=\"co0\">#access-control-allow-origin: *<\/span><br \/>\n<span class=\"co0\">#expires: Fri, 25 Jan 2019 23:07:17 GMT<\/span><br \/>\n<span class=\"co0\">#cache-control: max-age=600<\/span><br \/>\n<span class=\"co0\">#x-github-request-id: 8808:5B91:2A4802:2F2ADE:5C4B944C<\/span><br \/>\n<span class=\"co0\">#accept-ranges: bytes<\/span><br \/>\n<span class=\"co0\">#date: Fri, 25 Jan 2019 23:12:37 GMT<\/span><br \/>\n<span class=\"co0\">#via: 1.1 varnish<\/span><br \/>\n<span class=\"co0\">#age: 198<\/span><br \/>\n<span class=\"co0\">#x-served-by: cache-nrt6148-NRT<\/span><br \/>\n<span class=\"co0\">#x-cache: HIT<\/span><br \/>\n<span class=\"co0\">#x-cache-hits: 1<\/span><br \/>\n<span class=\"co0\">#x-timer: S1548457958.868588,VS0,VE0<\/span><br \/>\n<span class=\"co0\">#vary: Accept-Encoding<\/span><br \/>\n<span class=\"co0\">#x-fastly-request-id: b78ff4a19fdf621917cb6160b422d6a7155693a9<\/span><br \/>\n<span class=\"co0\">#content-length: 3602<\/span><\/p>\n<p><span class=\"kw2\">cat<\/span>\u00a0headers\u00a0<span class=\"sy0\">|<\/span>\u00a0<span class=\"kw2\">head<\/span>\u00a0<span class=\"re5\">-n<\/span>\u00a0<span class=\"nu0\">1<\/span>\u00a0<span class=\"sy0\">|<\/span>\u00a0<span class=\"kw2\">cut<\/span>\u00a0<span class=\"st_h\">&#8216;-d &#8216;<\/span>\u00a0<span class=\"st_h\">&#8216;-f2&#8217;<\/span><br \/>\n<span class=\"co0\"># get response code<\/span><br \/>\n<span class=\"co0\">## expect<\/span><br \/>\n<span class=\"co0\">#200<\/span><\/div>\n<\/div>\n<p>My site is up. Great!<\/p>\n<p>Now let\u2019s move on to making posts with curl in bash scripts.<\/p>\n<h3><strong>The third way: Making posts<\/strong><\/h3>\n<p>There will come a time when you need to make posts with curl in bash to authenticate to access or modification of private content. Such is the case working with APIs and html forms. It may require multiple curl requests. The placeholder curl command line for this way is as follows.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\">curl\u00a0<span class=\"re5\">-u<\/span>\u00a0<span class=\"re5\">-H<\/span>\u00a0<span class=\"re5\">&#8211;data<\/span>\u00a0<span class=\"co1\">${url}<\/span><br \/>\n<span class=\"co0\"># send crafted request<\/span><\/div>\n<\/div>\n<p>Making posts involves adding corresponding headers and data to allow for authentication.\u00a0 I\u2019ve prepared some examples of making posts with curl in bash.<\/p>\n<h4>Example) Basic authentication<\/h4>\n<p>Here is an example of using curl in bash scripts to download a file requiring basic authentication. Note that credentials are stored in a separate file called bash-curl-basic-auth-example-config.sh, which is also included below.<\/p>\n<p><u>curl-basic-auth.sh<\/u><\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\">#!\/bin\/bash<\/span><br \/>\n<span class=\"co0\">## curl-basic-auth<\/span><br \/>\n<span class=\"co0\">## &#8211; http basic authenication example using<\/span><br \/>\n<span class=\"co0\">##\u00a0\u00a0 curl in bash<\/span><br \/>\n<span class=\"co0\">## version 0.0.1<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n.\u00a0<span class=\"co1\">${SH2}<\/span><span class=\"sy0\">\/<\/span>cecho.sh\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># colored echo<\/span><br \/>\ncurl-basic-auth<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\ncecho yellow url:\u00a0<span class=\"co1\">${url}<\/span><br \/>\n<span class=\"kw3\">local<\/span>\u00a0username<br \/>\n<span class=\"kw3\">local<\/span>\u00a0<span class=\"kw2\">passwd<\/span><br \/>\n.\u00a0<span class=\"co1\">${FUNCNAME}<\/span>-config.sh\u00a0<span class=\"co0\"># ${username}, ${passwd}<\/span><br \/>\ncurl\u00a0<span class=\"re5\">-v<\/span>\u00a0<span class=\"re5\">-u<\/span>\u00a0<span class=\"co1\">${username}<\/span>:<span class=\"co1\">${password}<\/span>\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"re5\">&#8211;location<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"kw1\">if<\/span>\u00a0<span class=\"br0\">[<\/span>\u00a0<span class=\"co1\">${#}<\/span>\u00a0<span class=\"re5\">-eq<\/span>\u00a0<span class=\"nu0\">1<\/span>\u00a0<span class=\"br0\">]<\/span><br \/>\n<span class=\"kw1\">then<\/span><br \/>\n<span class=\"re2\">url<\/span>=<span class=\"st0\">&#8220;<span class=\"es3\">${1}<\/span>&#8220;<\/span><br \/>\n<span class=\"kw1\">else<\/span><br \/>\n<span class=\"kw3\">exit<\/span>\u00a0<span class=\"nu0\">1<\/span>\u00a0<span class=\"co0\"># wrong args<\/span><br \/>\n<span class=\"kw1\">fi<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\ncurl-basic-auth<br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"co0\">## generated by create-stub2.sh v0.1.1<\/span><br \/>\n<span class=\"co0\">## on Sun, 27 Jan 2019 14:04:18 +0900<\/span><br \/>\n<span class=\"co0\">## see &lt;https:\/\/github.com\/temptemp3\/sh2&gt;<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><\/div>\n<\/div>\n<p>Source:\u00a0<a href=\"https:\/\/github.com\/temptemp3\/linuxhint.com\/blob\/master\/curl-basic-auth.sh\">curl-basic-auth.sh<\/a><\/p>\n<p><u>curl-basic-auth-config.sh<\/u><\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\">#!\/bin\/bash<\/span><\/p>\n<p><span class=\"co0\">## curl-basic-auth-config<\/span><br \/>\n<span class=\"co0\">## version 0.0.1 &#8211; initial<\/span><\/p>\n<p><span class=\"co0\">##################################################<\/span><\/p>\n<p><span class=\"re2\">username<\/span>=<span class=\"st0\">&#8220;username&#8221;<\/span><br \/>\n<span class=\"re2\">password<\/span>=<span class=\"st0\">&#8220;passwd&#8221;<\/span><\/p>\n<p><span class=\"co0\">##################################################<\/span><\/p>\n<p><span class=\"co0\">## generated by create-stub2.sh v0.1.1<\/span><br \/>\n<span class=\"co0\">## on Sun, 27 Jan 2019 14:08:17 +0900<\/span><br \/>\n<span class=\"co0\">## see &lt;https:\/\/github.com\/temptemp3\/sh2&gt;<\/span><\/p>\n<p><span class=\"co0\">##################################################<\/span><\/div>\n<\/div>\n<p>Source:\u00a0<a href=\"https:\/\/github.com\/temptemp3\/linuxhint.com\/blob\/master\/curl-basic-auth-config.sh\">curl-basic-auth-config.sh<\/a><\/p>\n<p>Here\u2019s what it looks like in the command line.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"kw2\">bash<\/span>\u00a0bash-curl-basic-auth-example.sh URL<br \/>\n<span class=\"co0\">## expect response for url after basic authentication<\/span><\/div>\n<\/div>\n<p>Here you see how writing a bash script allows you to avoid having to include your secrets in the command line.<\/p>\n<p>Note that the \u2013location option was added to handle requests that are redirected.<\/p>\n<p>Now that we have basic authentication is out of the picture, let\u2019s step up the difficuly a bit.<\/p>\n<h4>Example) Submitting html form with csrf protection<\/h4>\n<p>The magic of bash is that you can do just about anything you have an intent to do. Jumping through the hoops of csrf protection is one way to kill it with curl in bash scripts.<\/p>\n<p>In modern web applications there is a security feature called csrf protection to prevent posts requests from anywhere without established access to the site in question.<\/p>\n<p>Basically, there is a security\u00a0<em>token<\/em>\u00a0included in the response of a page.<\/p>\n<p>Here what your bash script may look like to gain authorized access to a page content with csrf protection.<\/p>\n<p><u>curl-example.sh<\/u><\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\">#!\/bin\/bash<\/span><br \/>\n<span class=\"co0\">## curl-example<\/span><br \/>\n<span class=\"co0\">## &#8211; submits form with csrf protection<\/span><br \/>\n<span class=\"co0\">## version 0.0.1 &#8211; initial<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n.\u00a0<span class=\"co1\">${SH2}<\/span><span class=\"sy0\">\/<\/span>aliases<span class=\"sy0\">\/<\/span>commands.sh\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># subcommands<\/span><br \/>\n<span class=\"co0\">## specially crafted bash curl boilerplate for this example<\/span><br \/>\ntemplate-command-curl<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw3\">local<\/span>\u00a0method ;\u00a0<span class=\"re2\">method<\/span>=<span class=\"st0\">&#8220;<span class=\"es3\">${1}<\/span>&#8220;<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\n<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw3\">command<\/span>\u00a0curl\u00a0<span class=\"co1\">${url}<\/span>\u00a0\\<br \/>\nif-headers \\<br \/>\nif-data \\<br \/>\nif-options<br \/>\n<span class=\"br0\">}<\/span>\u00a0<span class=\"sy0\">|<\/span>\u00a0<span class=\"kw2\">tee<\/span>\u00a0<span class=\"co1\">${method}<\/span><span class=\"re5\">-response<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\ncurl-head<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw3\">local<\/span>\u00a0url ;\u00a0<span class=\"re2\">url<\/span>=<span class=\"st0\">&#8220;<span class=\"es3\">${url}<\/span>&#8220;<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\ntemplate-command-curl \\<br \/>\n<span class=\"kw2\">head<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\ncurl-get<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw3\">local<\/span>\u00a0url ;\u00a0<span class=\"re2\">url<\/span>=<span class=\"st0\">&#8220;<span class=\"es3\">${url}<\/span>&#8220;<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\ntemplate-command-curl \\<br \/>\nget<br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"co0\">## setup curl<\/span><br \/>\nif-headers<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw2\">true<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\nif-data<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw2\">true<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\nif-options<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw2\">true<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\ncurl-post<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw3\">local<\/span>\u00a0url ;\u00a0<span class=\"re2\">url<\/span>=<span class=\"st0\">&#8220;<span class=\"es3\">${url}<\/span>&#8220;<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\ntemplate-command-curl \\<br \/>\npost<br \/>\n<span class=\"br0\">}<\/span><br \/>\ncurl<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"co0\"># entry point for curl-head, curl-get, curl-post<\/span><br \/>\ncommands<br \/>\n<span class=\"br0\">}<\/span><br \/>\nmain<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"co0\">## rewrite url if needed etc<\/span><br \/>\n<span class=\"br0\">(<\/span>\u00a0<span class=\"co0\"># curl head request<\/span><br \/>\nif-options<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw2\">cat<\/span>\u00a0<span class=\"co2\">&lt;&lt; EOF<br \/>\n&#8211;location<br \/>\nEOF<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\ncurl\u00a0<span class=\"kw2\">head<\/span>\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"sy0\">&gt;<\/span>\u00a0head-response<br \/>\n<span class=\"br0\">)<\/span><br \/>\n<span class=\"kw3\">test<\/span>\u00a0<span class=\"st0\">&#8220;<span class=\"es4\">$( cat head-response | grep -e \u2018Location:\u2019 )<\/span>&#8220;<\/span>\u00a0<span class=\"sy0\">||<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"co0\">## block reassigning url base on head response location<\/span><br \/>\n<span class=\"re2\">url<\/span>=\u2026<br \/>\n<span class=\"br0\">}<\/span><br \/>\nreset-curl<br \/>\n<span class=\"co0\">## setup curl &#8230;<\/span><br \/>\ncurl get\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"co0\"># &gt; get-response<\/span><br \/>\nextract-info-for-post-request\u00a0<span class=\"co0\"># &lt; get-reponse, extracts token and other info for post<\/span><br \/>\n<span class=\"co0\">## reset curl and setup if needed \u2026<\/span><br \/>\ncurl post\u00a0<span class=\"co1\">${url}<\/span>\u00a0<span class=\"co0\"># &gt; post-response<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\ncurl-example<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw2\">true<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"kw1\">if<\/span>\u00a0<span class=\"br0\">[<\/span>\u00a0<span class=\"co1\">${#}<\/span>\u00a0<span class=\"re5\">-eq<\/span>\u00a0<span class=\"nu0\">0<\/span>\u00a0<span class=\"br0\">]<\/span><br \/>\n<span class=\"kw1\">then<\/span><br \/>\n<span class=\"kw2\">true<\/span><br \/>\n<span class=\"kw1\">else<\/span><br \/>\n<span class=\"kw3\">exit<\/span>\u00a0<span class=\"nu0\">1<\/span>\u00a0<span class=\"co0\"># wrong args<\/span><br \/>\n<span class=\"kw1\">fi<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\ncurl-example<br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"co0\">## generated by create-stub2.sh v0.1.1<\/span><br \/>\n<span class=\"co0\">## on Sun, 27 Jan 2019 16:36:17 +0900<\/span><br \/>\n<span class=\"co0\">## see &lt;https:\/\/github.com\/temptemp3\/sh2&gt;<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><\/div>\n<\/div>\n<p>Source:\u00a0<a href=\"https:\/\/github.com\/temptemp3\/linuxhint.com\/blob\/master\/curl-example.sh\">curl-example.sh<\/a><\/p>\n<p><u>Notes on script<\/u><br \/>\nIt uses a alias called commands that I mentioned in a previous post about the\u00a0<a href=\"https:\/\/linuxhint.com\/bash_declare_command\/\">bash declare command<\/a>, which makes it possible to declare subcommands implicitly by way of convention.<\/p>\n<p>Here you see that bash can be used to string curl request together with logic to carry out the intent of your script.<br \/>\nSo that some of the bash usage above using subshells to limit function redeclaration scope doesn\u2019t appear so magical, I\u2019ve prepared a follow-up example.<\/p>\n<p><u>subshell-functions.sh<\/u><\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\">#!\/bin\/bash<\/span><br \/>\n<span class=\"co0\">## subshell-functions<\/span><br \/>\n<span class=\"co0\">## version 0.0.1 &#8211; initial<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\nd<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw2\">true<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\nc<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw2\">true<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\nb<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw2\">true<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span><br \/>\na<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"br0\">{<\/span>\u00a0b ; c ; d ;\u00a0<span class=\"br0\">}<\/span><br \/>\n<span class=\"br0\">(<\/span><br \/>\nb<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw2\">cat<\/span>\u00a0<span class=\"co2\">&lt;&lt; EOF<br \/>\nI am b<br \/>\nEOF<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"br0\">{<\/span>\u00a0b ; c ; d ;\u00a0<span class=\"br0\">}<\/span><br \/>\n<span class=\"br0\">)<\/span><br \/>\n<span class=\"br0\">{<\/span>\u00a0b ; c ; d ;\u00a0<span class=\"br0\">}<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"kw1\">if<\/span>\u00a0<span class=\"br0\">[<\/span>\u00a0<span class=\"co1\">${#}<\/span>\u00a0<span class=\"re5\">-eq<\/span>\u00a0<span class=\"nu0\">0<\/span>\u00a0<span class=\"br0\">]<\/span><br \/>\n<span class=\"kw1\">then<\/span><br \/>\n<span class=\"kw2\">true<\/span><br \/>\n<span class=\"kw1\">else<\/span><br \/>\n<span class=\"kw3\">exit<\/span>\u00a0<span class=\"nu0\">1<\/span>\u00a0<span class=\"co0\"># wrong args<\/span><br \/>\n<span class=\"kw1\">fi<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\na<br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"co0\">## generated by create-stub2.sh v0.1.1<\/span><br \/>\n<span class=\"co0\">## on Sun, 27 Jan 2019 13:43:50 +0900<\/span><br \/>\n<span class=\"co0\">## see &lt;https:\/\/github.com\/temptemp3\/sh2&gt;<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><\/div>\n<\/div>\n<p>Source:\u00a0<a href=\"https:\/\/github.com\/temptemp3\/linuxhint.com\/blob\/master\/subshell-functions.sh\">subshell-functions.sh<\/a><\/p>\n<p>Here is the correspondence command line example.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"kw2\">bash<\/span>\u00a0a.sh<br \/>\n<span class=\"co0\">## expect<\/span><br \/>\nI am b<\/div>\n<\/div>\n<h4>Example) Wonderlist API call<\/h4>\n<p>Here is curl request command line in a bash script that I wrote in late 2017 back before switching over to Trello.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\">curl \\<br \/>\n<span class=\"co1\">${X}<\/span>\u00a0\\<br \/>\n<span class=\"co1\">${url}<\/span>\u00a0\\<br \/>\n<span class=\"re5\">-H<\/span>\u00a0<span class=\"st0\">&#8220;X-Access-Token:\u00a0<span class=\"es3\">${WL_AT}<\/span>&#8220;<\/span>\u00a0\\<br \/>\n<span class=\"re5\">-H<\/span>\u00a0<span class=\"st0\">&#8220;X-Client-ID:\u00a0<span class=\"es3\">${WL_CID}<\/span>&#8220;<\/span>\u00a0\\<br \/>\n<span class=\"re5\">&#8211;silent<\/span><\/div>\n<\/div>\n<p>Source:\u00a0<a href=\"https:\/\/github.com\/temptemp3\/wunderlist.sh\/blob\/master\/main.sh#L40\">wonderlist.sh\/main.sh: Line 40<\/a><\/p>\n<p><u>Notes on script<\/u><\/p>\n<p>${X} contains an -X option that can be passed in by caller functions. If you are not familiar with the option, it is set the request command to use. That is, GET, POST, HEAD, etc. according to to api documentation.<\/p>\n<p>It contains multiple -H options for authenication.<\/p>\n<p>The \u2013silent option is used because in some cases showing progress in the terminal would be overkill for background requests.<\/p>\n<p>Surely, you are now killing it with curl in bash scripts. Next, we move on to special topics to bring it all together.<\/p>\n<h3>Looping through urls with curl in bash<\/h3>\n<p>Suppose that we have a list of URLs which we would like to loop over and curl. That is, we want download using curl for each URL in our list. Here is how we would go about accomplishing this task on the command line.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\">## method (1)<\/span><\/p>\n<p>curl<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw3\">echo<\/span>\u00a0<span class=\"st0\">&#8220;dummy response for\u00a0<span class=\"es3\">${@}<\/span>&#8220;<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># fake curl for testing purposes<\/span><\/p>\n<p>urls<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw2\">cat<\/span>\u00a0<span class=\"sy0\">\/<\/span>dev<span class=\"sy0\">\/<\/span>clipboard ;\u00a0<span class=\"br0\">}<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># returns list of urls<\/span><\/p>\n<p><span class=\"kw1\">for<\/span>\u00a0url\u00a0<span class=\"kw1\">in<\/span>\u00a0$<span class=\"br0\">(<\/span>\u00a0urls\u00a0<span class=\"br0\">)<\/span>;\u00a0<span class=\"kw1\">do<\/span>\u00a0curl\u00a0<span class=\"co1\">${url}<\/span>;\u00a0<span class=\"kw1\">done<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># curl loop<\/span><\/p>\n<p><span class=\"co0\">## expect<\/span><br \/>\n<span class=\"co0\">#dummy response for whatever is in your<\/span><br \/>\n<span class=\"co0\">#dummy response for clipboard<\/span><br \/>\n<span class=\"co0\">#dummy response for &#8230;<\/span><\/div>\n<\/div>\n<p>If you don\u2019t have a list of urls to copy on hand, here is a list of 100 URLs most likely respond to HTTP request using curl.<\/p>\n<p>gist of\u00a0<a href=\"https:\/\/gist.github.com\/demersdesigns\/4442cd84c1cc6c5ccda9b19eac1ba52b\">Craft Popular URLs<\/a>\u00a0based on list of the most popular websites worldwide<\/p>\n<p>Often, we do not only wish to curl a list of urls in bash. We may want to generate urls to curl as we progress through the loop. To accomplish this task, we need to introduce variables into the URL as follows.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\">## method (2)<\/span><\/p>\n<p>curl<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw3\">echo<\/span>\u00a0<span class=\"st0\">&#8220;dummy response for\u00a0<span class=\"es3\">${@}<\/span>&#8220;<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># fake curl for testing purposes<\/span><br \/>\nurl<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0<span class=\"kw3\">echo<\/span>\u00a0<span class=\"co1\">${url_base}<\/span><span class=\"sy0\">\/<\/span><span class=\"co1\">${i}<\/span>\u00a0;\u00a0<span class=\"br0\">}<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># url template<\/span><br \/>\nurls<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># generate all urls<\/span><br \/>\n<span class=\"kw3\">local<\/span>\u00a0i<br \/>\n<span class=\"kw1\">for<\/span>\u00a0i\u00a0<span class=\"kw1\">in<\/span>\u00a0<span class=\"co1\">${range}<\/span><br \/>\n<span class=\"kw1\">do<\/span><br \/>\nurl<br \/>\n<span class=\"kw1\">done<\/span><br \/>\n<span class=\"br0\">}<\/span><\/p>\n<p><span class=\"re2\">url_base<\/span>=<span class=\"st0\">&#8220;https:\/\/temptemp3.github.io&#8221;<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># just some base<\/span><br \/>\n<span class=\"re2\">range<\/span>=$<span class=\"br0\">(<\/span>\u00a0<span class=\"kw3\">echo<\/span>\u00a0<span class=\"br0\">{<\/span><span class=\"nu0\">1<\/span>..<span class=\"nu0\">9<\/span><span class=\"br0\">}<\/span>\u00a0<span class=\"br0\">)<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># just some range<\/span><br \/>\n<span class=\"kw1\">for<\/span>\u00a0url\u00a0<span class=\"kw1\">in<\/span>\u00a0$<span class=\"br0\">(<\/span>\u00a0urls\u00a0<span class=\"br0\">)<\/span>;\u00a0<span class=\"kw1\">do<\/span>\u00a0curl\u00a0<span class=\"co1\">${url}<\/span>;\u00a0<span class=\"kw1\">done<\/span>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<span class=\"co0\"># curl loop<\/span><\/p>\n<p><span class=\"co0\">## expect<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/1<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/2<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/3<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/4<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/5<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/6<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/7<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/8<\/span><br \/>\n<span class=\"co0\">#dummy response for https:\/\/temptemp3.github.io\/9<\/span><\/div>\n<\/div>\n<p>It turns out that loops may be avoided in some cases by taking advantage of a curl feature only available in command line called URL globbing. Here\u2019s how it works.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\"># method (3)<\/span><\/p>\n<p><span class=\"kw3\">unset<\/span>\u00a0<span class=\"re5\">-f<\/span>\u00a0curl<br \/>\n<span class=\"co0\"># included just in case<\/span><br \/>\ncurl https:<span class=\"sy0\">\/\/<\/span>temptemp3.github.io<span class=\"sy0\">\/<\/span><span class=\"br0\">[<\/span><span class=\"nu0\">0<\/span>&#8211;<span class=\"nu0\">9<\/span><span class=\"br0\">]<\/span><br \/>\n<span class=\"co0\"># curl loop using URL globbing<\/span><\/p>\n<p><span class=\"co0\">## expect<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/1<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/2<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/3<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/4<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/5<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/6<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/7<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/8<\/span><br \/>\n<span class=\"co0\">#response for https:\/\/temptemp3.github.io\/9<\/span><\/div>\n<\/div>\n<p>Here we see that any of the methods above may be used to implement a curl loop in bash Depending on the use case and desired level of control, a method may be preferred over another.<\/p>\n<h3>Handling curl errors in bash<\/h3>\n<p>One thing that is absent from curl is the ability to handle errors. That is where bash\u00a0 comes in handly.<\/p>\n<p>Curl has an\u2013retry NUM option that as you may have guess tells curl to retry a specific number of times. However, what if we want to have curl effectively retry indefinitely until succeeding?<\/p>\n<p><u>curl-bashh-retry.sh<\/u><\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"co0\">#!\/bin\/bash<\/span><br \/>\n<span class=\"co0\">## curl-retry<\/span><br \/>\n<span class=\"co0\">## &#8211; retries curl indefinitely<\/span><br \/>\n<span class=\"co0\">## version 0.0.1<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\ncar<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw3\">echo<\/span>\u00a0<span class=\"st0\">&#8220;<span class=\"es3\">${1}<\/span>&#8220;<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\ncurl-error-code<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw3\">test<\/span>\u00a0<span class=\"sy0\">!<\/span>\u00a0<span class=\"re5\">-f<\/span>\u00a0<span class=\"st0\">&#8220;curl-error&#8221;<\/span>\u00a0<span class=\"sy0\">||<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\ncar $<span class=\"br0\">(<\/span><br \/>\n<span class=\"kw2\">cat<\/span>\u00a0curl-error \\<br \/>\n<span class=\"sy0\">|<\/span>\u00a0<span class=\"kw2\">sed<\/span>\u00a0\\<br \/>\n<span class=\"re5\">-e<\/span>\u00a0<span class=\"st_h\">&#8216;s\/[^0-9 ]\/\/g&#8217;<\/span><br \/>\n<span class=\"br0\">)<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\ncurl-retry<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw1\">while<\/span>\u00a0<span class=\"br0\">[<\/span>\u00a0<span class=\"sy0\">!<\/span>\u00a0<span class=\"br0\">]<\/span><br \/>\n<span class=\"kw1\">do<\/span><br \/>\ncurl temptemp3.sh\u00a0<span class=\"nu0\">2<\/span><span class=\"sy0\">&gt;<\/span>curl-error\u00a0<span class=\"sy0\">||<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"kw1\">case<\/span>\u00a0$<span class=\"br0\">(<\/span>\u00a0curl-error-code\u00a0<span class=\"br0\">)<\/span>\u00a0<span class=\"kw1\">in<\/span><br \/>\n<span class=\"nu0\">6<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"co0\">### handle error code 6<\/span><br \/>\n<span class=\"kw3\">echo<\/span>\u00a0curl unable to resolve host<br \/>\n<span class=\"br0\">}<\/span>\u00a0<span class=\"sy0\">;;<\/span><br \/>\n<span class=\"sy0\">*<\/span><span class=\"br0\">)<\/span>\u00a0<span class=\"br0\">{<\/span><br \/>\n<span class=\"co0\"># &lt;https:\/\/curl.haxx.se\/libcurl\/c\/libcurl-errors.html&gt;<\/span><br \/>\n<span class=\"kw2\">true<\/span>\u00a0<span class=\"co0\"># not yet implemented<\/span><br \/>\n<span class=\"br0\">}<\/span>\u00a0<span class=\"sy0\">;;<\/span><br \/>\n<span class=\"kw1\">esac<\/span><br \/>\n<span class=\"kw2\">sleep<\/span>\u00a0<span class=\"nu0\">1<\/span><br \/>\n<span class=\"kw3\">continue<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"kw3\">break<\/span><br \/>\n<span class=\"kw1\">done<\/span><br \/>\n<span class=\"br0\">}<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"kw1\">if<\/span>\u00a0<span class=\"br0\">[<\/span>\u00a0<span class=\"co1\">${#}<\/span>\u00a0<span class=\"re5\">-eq<\/span>\u00a0<span class=\"nu0\">0<\/span>\u00a0<span class=\"br0\">]<\/span><br \/>\n<span class=\"kw1\">then<\/span><br \/>\n<span class=\"kw2\">true<\/span><br \/>\n<span class=\"kw1\">else<\/span><br \/>\n<span class=\"kw3\">exit<\/span>\u00a0<span class=\"nu0\">1<\/span>\u00a0<span class=\"co0\"># wrong args<\/span><br \/>\n<span class=\"kw1\">fi<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\ncurl-retry<br \/>\n<span class=\"co0\">##################################################<\/span><br \/>\n<span class=\"co0\">## generated by create-stub2.sh v0.1.1<\/span><br \/>\n<span class=\"co0\">## on Sun, 27 Jan 2019 15:58:51 +0900<\/span><br \/>\n<span class=\"co0\">## see &lt;https:\/\/github.com\/temptemp3\/sh2&gt;<\/span><br \/>\n<span class=\"co0\">##################################################<\/span><\/div>\n<\/div>\n<p>Source:\u00a0<a href=\"https:\/\/github.com\/temptemp3\/linuxhint.com\/blob\/master\/curl-retry.sh\">curl-retry.sh<\/a><br \/>\nHere is what we see in command line.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\"><span class=\"kw2\">bash<\/span>\u00a0curl-bash-retry.sh<br \/>\n<span class=\"co0\">## expect<\/span><br \/>\n<span class=\"co0\">#curl unable to resolve host<\/span><br \/>\n<span class=\"co0\">#curl unable to resolve host<\/span><br \/>\n<span class=\"co0\">#&#8230;<\/span><\/div>\n<\/div>\n<p>The hope is that eventually someone will create temptemp3.io and our script will exit with an exit status of zero.<\/p>\n<p>Last but not least I would like to end with an example of how to set up concurrent curls in bash to act as a download accelerator.<\/p>\n<h3>Downldr.sh<\/h3>\n<p>Sometimes it is helpful to download large files in parts. Here is a snippet from a bash script that I wrote recently using curl.<\/p>\n<div class=\"codecolorer-container bash default\">\n<div class=\"bash codecolorer\">curl \\<br \/>\n<span class=\"co1\">${src}<\/span>\u00a0\\<br \/>\n<span class=\"re5\">-r<\/span>\u00a0$<span class=\"br0\">(<\/span><span class=\"br0\">(<\/span>\u00a0<span class=\"co1\">${i}<\/span><span class=\"sy0\">*<\/span><span class=\"co1\">${chunk_size}<\/span>\u00a0<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span>-$<span class=\"br0\">(<\/span><span class=\"br0\">(<\/span>\u00a0<span class=\"br0\">(<\/span>\u00a0<span class=\"br0\">(<\/span><span class=\"co1\">${i}<\/span>+<span class=\"nu0\">1<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">*<\/span><span class=\"co1\">${chunk_size}<\/span>\u00a0<span class=\"br0\">)<\/span>\u00a0&#8211;\u00a0<span class=\"nu0\">1<\/span>\u00a0<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span>\u00a0\\<br \/>\n<span class=\"re5\">-o<\/span>\u00a0<span class=\"co1\">${src_base}<\/span><span class=\"re5\">-part<\/span><span class=\"co1\">${i}<\/span><\/div>\n<\/div>\n<p>Source:\u00a0<a href=\"https:\/\/github.com\/temptemp3\/downldr.sh\/blob\/master\/downldr.sh#L11\">downldr.sh\/downldr.sh: Line 11<\/a><\/p>\n<p><u>Notes on script<\/u><\/p>\n<p>The -r option is used to specifiy the range in bytes to download if the host accepts ranges.<\/p>\n<h4>Conclusion<\/h4>\n<p>By this time you are killing it with curl in bash scripts. In many cases you may take advantage of curl functionality through the horde of options it provides. However, you may opt out and achieve the same functionality outside of curl in bash for the level of control that fits your needs.<\/p>\n<p><a href=\"https:\/\/linuxhint.com\/curl_bash_examples\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019ve ever sat in front of a terminal, typed \u2018curl\u2019, pasted the URL of something you want to download, and hit enter, cool! You\u2019re going to be killing it with curl in bash scripts in no time. Here you will learn how to use curl in bash scripts and important tips and tricks for &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/02\/03\/curl-in-bash-scripts-by-example-linux-hint\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Curl in Bash Scripts by Example \u2013 Linux Hint&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-9102","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/9102","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/comments?post=9102"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/9102\/revisions"}],"predecessor-version":[{"id":12457,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/9102\/revisions\/12457"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/media?parent=9102"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/categories?post=9102"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/tags?post=9102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}