{"id":501,"date":"2019-08-05T22:00:53","date_gmt":"2019-08-06T02:00:53","guid":{"rendered":"http:\/\/richrijnders.com\/?p=501"},"modified":"2020-12-12T15:32:38","modified_gmt":"2020-12-12T20:32:38","slug":"shell-script-trim-args","status":"publish","type":"post","link":"https:\/\/richrijnders.com\/shell-script-trim-args\/","title":{"rendered":"BASH 01: Trim Your Args!"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;3.26.6&#8243;][et_pb_row _builder_version=&#8221;3.26.6&#8243; custom_padding=&#8221;||16px|||&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;3.26.6&#8243;][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2019\/08\/kbd_banner_21189847.jpg&#8221; align=&#8221;center&#8221; force_fullwidth=&#8221;on&#8221; _builder_version=&#8221;4.7.6&#8243; hover_enabled=&#8221;0&#8243; title_text=&#8221;kbd_banner_21189847&#8243; sticky_enabled=&#8221;0&#8243;][\/et_pb_image][et_pb_text _builder_version=&#8221;3.27.4&#8243; text_orientation=&#8221;justify&#8221; text_text_align=&#8221;justify&#8221;]<\/p>\n<p>Ideally I wanted to put this article in a category called <em>&#8220;Stuff we all need to know but never get around to master&#8221;<\/em>\u00a0because, for me, that is squarely where the subject of shell scripting (BASH, SH, et. al.) firmly lived for way too long. As software developers, \u00a0we are experts in our respective platforms. Whether that be mobile apps, cloud API&#8217;s, or MRP \/ ERP back-end behemoths, we know the interplay of our code and interfaces to our cores. But every so often we all end up in a situation that requires us do some dreaded shell scripting to solve a specific problem. When this happens we can be seen floundering about; confounded by this thing that seems to be a simple coding language but never seems to work the way we think it should. So we search the internets for some piece of script that appears to do something close to what we need. Then we tweak this strange bunch of back-ticks, curly braces, and escape characters until we get the desired outcome (maybe). But we never\u00a0<em>really<\/em> understand what it&#8217;s doing. I never liked this, so when I needed to develop more sophisticated HLL-type utilities in BASH that were to become a fixed part of a major application, I made it a point to\u00a0really dig in, develop, and\u00a0<em>understand<\/em> SH and BASH scripting.<\/p>\n<p>In this series of articles, I thought it might be useful to discuss shell scripting in terms of small\u00a0<em>Code Snippets &#8211;\u00a0<\/em>imparting some shell scripting knowledge and demystification through the dissection of actual working, useful, <em>and re-usable<\/em> code. In this first article we will discuss a simple <em>trim()<\/em>\u00a0function. It does the same thing as similarly named built in functions (BIF&#8217;s) of high level languages (HLL&#8217;s). It will strip any leading or trailing whitespace characters from a string variable passed to it. We all know our applications should not trust data that originates from external, untrusted, sources. Any data passed in to our shell scripts as a string argument should be devoid of leading or trailing whitespace (CR\/LF, TAB, etc). Such whitespace can cause havoc in our code if that string is blindly used in downstream operations so, we must trim() them.\u00a0<\/p>\n<p>Below is our sample script containing the\u00a0<em>trim()<\/em> function. It might be helpful if you right-click and open the image in a separate browser window so you can follow along with the discussion. Alternately, you can\u00a0<div class=\"sdm_download_button_box_default\"><div class=\"sdm_download_link\"><a href=\"https:\/\/richrijnders.com\/?sdm_process_download=1&download_id=557\" class=\"sdm_download green\" title=\"sample_trim-whitespace.sh.zip\" >Download Source File<\/a><\/div><\/div> and open it in your favorite text editor to follow along.\u00a0<\/p>\n<p>[\/et_pb_text][et_pb_image src=&#8221;https:\/\/richrijnders.com\/file\/2019\/08\/TrimYourArgs_AnnotatedCode.jpg&#8221; force_fullwidth=&#8221;on&#8221; _builder_version=&#8221;4.7.6&#8243; hover_enabled=&#8221;0&#8243; box_shadow_style=&#8221;preset4&#8243; title_text=&#8221;TrimYourArgs_AnnotatedCode&#8221; sticky_enabled=&#8221;0&#8243;][\/et_pb_image][et_pb_text _builder_version=&#8221;3.27.4&#8243; text_orientation=&#8221;justify&#8221; text_text_align=&#8221;justify&#8221;]<\/p>\n<h2>Some Basics<\/h2>\n<p>The first thing you will notice is that I like to structure my scripts the same way I do any other application or program. We start with the &#8220;Shabang&#8221; line which points to where our BASH interpreter resides. Following that is a basic documentation box with the typical attributions and revision information.<\/p>\n<p><span style=\"font-size: 14px;\">The next section <\/span><span style=\"font-size: 14px; color: #e02b20;\"><strong>(a)<\/strong> <\/span><span style=\"font-size: 14px;\">is something I put at the top of my BASH scripts. It retrieves variables that I find I often need in my scripts for one reason or another.<\/span><\/p>\n<p>LINE 22: Determines the absolute path in the systems file directory where the running instance of the script was loaded from and saves that information in a variable named SCRIPTPATH. This variable is defined as READONLY since there is no reason for it to be changed. Why might you need this information? \u00a0Within your script you may need to access other resources that are expected to be in the same location as this script or else you may need to write messages to a log that need to identify the location of the running script. Also, you may need to pass this information to other commands or utilities that don&#8217;t work with relative paths. \u00a0How this odd string of characters accomplishes this is a discussion perhaps for another article. Suffice it to say that you may see some shorter code that purports to accomplish the same thing, but those have issues when the script was executed using a relative reference (ie: &#8220;..\/myscript&#8221;) and the above is thus far the only reliable way I have found to always get the full, absolute path.<\/p>\n<p>LINE 25: Retrieves the name of the running script. You might think this odd since your script should have a fixed name, no? No. Script files are often renamed when used or cloned and modified for similar application implementations. If the name of the script is needed for instance, to load a configuration file with the same file name prefix as the script, then retrieving it dynamically avoids pitfalls when the script is renamed and avoids having to do scan-and-replace operations on the code whenever it is renamed.<\/p>\n<p>LINE 28: Retrieves the PID (process ID) of this instance of the running script. AKA the\u00a0<em>thread<\/em>. This is useful for logging when there might be multiple instances of this script running concurrently on the system or when spawning an error recovery operation to clean up (kill) this running process if an unrecoverable error occurs.<\/p>\n<p>&nbsp;<\/p>\n<p>[\/et_pb_text][et_pb_text _builder_version=&#8221;3.27.4&#8243; header_4_font=&#8221;Roboto Mono||||||||&#8221; header_4_text_color=&#8221;#0c71c3&#8243; header_4_font_size=&#8221;14px&#8221; header_6_font=&#8221;Roboto Mono||||||||&#8221; header_6_text_color=&#8221;#0c71c3&#8243; header_6_font_size=&#8221;12px&#8221; text_orientation=&#8221;justify&#8221; text_text_align=&#8221;justify&#8221; inline_fonts=&#8221;Roboto Mono&#8221;]<\/p>\n<h2>The Trim() Function<\/h2>\n<p>LINE 37: <strong><span style=\"color: #e02b20;\">(b)<\/span><\/strong> is where the meat of our discussion takes place. This is where we difine our re-usable trim() function. \u00a0In shell scripting, a function is simply defined by its name followed by open and close parenthesis and delimited by an opening curly brace and closed curly brace.\u00a0Script functions do not require arguments to the function to be defined. Just like arguments passed to the script itself, arguments passed to the function are referenced within the function simply as the variables $1, $2, etc. You can see the argument being passed into the function being referenced as $1 on LINE 39.<\/p>\n<p><span style=\"font-size: 14px;\">Our goal is that our function should behave as much like a function in an HLL as possible. Ideally we want to simply pass a variable to the function and have it trimmed.\u00a0<\/span><span style=\"font-size: 14px;\">But script functions do not have the capability to return a value to the caller. For example:<\/span><span style=\"font-size: 14px;\">\u00a0<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">myTrimmedString=trim ${myString}\u00a0 \/\/ not valid in a shell script<\/span><\/p>\n<p><span style=\"font-size: 14px;\">Is not valid because trim() can not return a value.\u00a0Without the ability for a function to return a value, our only option is to set the result to a global variable that can be accessed after the function call. Yet if that result variable is set inside the function, then it must be hard-coded and will be the same for each call to the function, resulting in code like so:<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">trim ${myString}<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">myString=${trimResultVar}<\/span><\/p>\n<p><span style=\"font-size: 14px;\">In the above example, the defined trim function would take the input argument as a string, trim the leading and trailing whitespace, and then assign that trimmed value to a hard-coded global variable named <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">trimResultVar<\/span><span style=\"font-size: 14px;\">. Not only is this messy code, but it requires that the code outside the function have knowledge of the result variable name used inside the function. There is also no obvious connection between the two lines of code above which makes the code hard to follow.<\/span><\/p>\n<p><span style=\"font-size: 14px;\">But we have a better solution.\u00a0<\/span><\/p>\n<p><span style=\"font-size: 14px;\">You will note in our sample program on LINE 55 that when we invoke\u00a0<\/span><span style=\"font-size: 14px;\">our trim() function, we pass<\/span><span style=\"font-size: 14px;\">\u00a0<\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">myArg<\/span><span style=\"font-size: 14px;\">\u00a0as a literal to the function and not<\/span><span style=\"font-size: 14px;\">\u00a0<\/span><span style=\"font-size: 14px; font-family: 'Roboto Mono'; color: #0c71c3;\">${myArg}<\/span><span style=\"font-size: 14px;\">\u00a0the variable. This is because we are passing the variable\u00a0<\/span><em style=\"font-size: 14px;\">name<\/em><span style=\"font-size: 14px;\">\u00a0to the function, <\/span><em style=\"font-size: 14px;\"><strong>not<\/strong><\/em><span style=\"font-size: 14px;\"> the actual string of text that we want trimmed. LINE 39 in our trim() function takes the name of the variable (that contains the text to be trimmed) and assigns that to a local variable named <span style=\"color: #0c71c3; font-family: 'Roboto Mono';\">_varName<\/span>. The <span style=\"color: #0c71c3; font-family: 'Roboto Mono';\">local<\/span> qualifier limits the scope of the variable to only the local function block and the leading underscore in the variable name is a commonly accepted convention for localized variables. \u00a0Then, LINE 40\u00a0<em>dereferences\u00a0<\/em>that variable name to get its value (the string to be trimmed) and assigns that string to another local variable <span style=\"color: #0c71c3; font-family: 'Roboto Mono';\">_str<\/span>.\u00a0The exclamation point in the dereference statement causes the string of characters following it to be treated as a variable that contains another variable name (a &#8220;varvar&#8221;), expands it to its contents, and then retrieves the value of the variable having <em>that<\/em> name. \u00a0<\/span><\/p>\n<p><span style=\"font-size: 14px;\">Example:<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">myVar=&#8217;abcdef&#8217;<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">myVarName=&#8217;myVar&#8217;<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">echo ${myVar} \u00a0\/\/ prints &#8216;abcdef&#8217;<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">echo ${myVarName} \/\/ prints &#8216;myVar&#8217;<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">echo ${!myVarName} \u00a0\/\/ prints &#8216;abcdef&#8217;<\/span><\/p>\n<p><span style=\"font-size: 14px;\">Now that we have both the name of the variable to be trimmed (<\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_varName<\/span><span style=\"font-size: 14px;\">) and its value (<\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_str<\/span><span style=\"font-size: 14px;\">) we can trim any leading and trailing whitespace from the value on LINE 42 <\/span><strong style=\"font-size: 14px;\"><span style=\"color: #e02b20;\">(c)<\/span><\/strong><span style=\"font-size: 14px;\">. This looks like one of those cases of scripting &#8220;voodoo&#8221; where some of us would just be tempted to copy\/paste and then tweak until we get the desired result. But if you don&#8217;t understand what is happening there then you have no clear concept of either the long term stability of your application or the security implications for your system. Besides, it&#8217;s not all that complex to understand, so let&#8217;s break it down.<\/span><\/p>\n<p><span style=\"font-size: 14px;\">The first part of the line is the assignment:<\/span><\/p>\n<p><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_str=&#8221;$(<\/span><span style=\"font-size: 14px;\"> &#8230; <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">)&#8221;<\/span><\/p>\n<p><span style=\"font-size: 14px;\">If you are not familiar with this method of assigning a value to a variable, it is called\u00a0<\/span><em style=\"font-size: 14px;\">command substitution<\/em><span style=\"font-size: 14px;\">. It just takes the results of any command you put between the parens and assigns that result to the variable. The command we put inside the parens is what is removing the whitespace. So let us look more closely at that command.<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-weight: normal;\"><\/span><\/p>\n<p><span style=\"font-size: 14px;\">The first part of the command is pretty straight forward and we all probably get it:<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">echo -e &#8220;$_str&#8221;<\/span><\/p>\n<p><span style=\"font-size: 14px;\">On its face, this statement simply outputs the value of the variable <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_str<\/span><span style=\"font-size: 14px;\">. More accurately, it outputs the contents of <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_str<\/span><span style=\"font-size: 14px;\">\u00a0to <\/span><em style=\"font-size: 14px;\">stdout<\/em><span style=\"font-size: 14px;\"> (the standard output). The <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">-e<\/span><span style=\"font-size: 14px;\"> option is there just to enable backslash escaped characters if they happen to be in the string variable. The next part of our command is the pipe character <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">|.<\/span><span style=\"font-size: 14px;\"> This operator simply sends the results of whatever command is in front of it (in this case, our echo command) to the\u00a0<\/span><em style=\"font-size: 14px;\">stdin<\/em><span style=\"font-size: 14px;\"> of whatever command follows it.\u00a0<\/span><\/p>\n<p><span style=\"font-size: 14px;\">What follows it is an invocation of the <\/span><a href=\"https:\/\/linux.die.net\/man\/1\/sed\" style=\"font-size: 14px;\">sed<\/a><span style=\"font-size: 14px;\"> utility. sed is a *nix utility that performs basic stream editing on an input stream or file. In this case, we are asking sed to perform two operations on the stream of characters we are sending to its\u00a0<\/span><em style=\"font-size: 14px;\">stdin<\/em><span style=\"font-size: 14px;\"> via our pipe symbol. The first operation:<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">s\/^[[:space:]]*\/\/<\/span><\/p>\n<p><span style=\"font-size: 14px;\">is a\u00a0<\/span><em style=\"font-size: 14px;\">regular expression<\/em><span style=\"font-size: 14px;\"> that will remove any leading whitespace from the string\/stream. The second operation:<\/span><\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-size: 14px;\">s\/[[:space:]]*$\/\/<\/span><\/p>\n<p><span style=\"font-size: 14px;\">is another <\/span><em style=\"font-size: 14px;\">regular expression<\/em><span style=\"font-size: 14px;\"> that will remove any trailing whitespace from the string\/stream.\u00a0If you are unfamiliar with how regular expressions work, there are many very good tutorials out there that are easily found with an internet search. The <\/span><span style=\"font-size: 14px; color: #0c71c3;\">-e<\/span><span style=\"font-size: 14px;\"> option is different for sed than for the echo command. For sed, the -e option is a way to stack a number of operations to be performed on the same string\/stream. So in this case, the -e options allow us to stack the two regular expressions described above so that they are both performed on our string in a single pass.\u00a0<\/span><\/p>\n<p><span style=\"font-size: 14px;\">So much for the &#8220;voodoo&#8221; line. Breaking it down into its constituent parts, we can see and understand what is really happening. We have passed the contents of the <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_str<\/span><span style=\"font-size: 14px;\"> variable to the <\/span><span style=\"font-size: 14px; color: #0c71c3;\">sed<\/span><span style=\"font-size: 14px;\"> utility that uses regular expressions to strip leading and trailing whitespace, and we assign the results right back into the <\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_str<\/span><span style=\"font-size: 14px;\"> variable.<\/span><\/p>\n<p><span style=\"font-size: 14px;\">The last line of our function <strong><span style=\"color: #e02b20;\">(d)<\/span><\/strong> takes the trimmed results currently stored in the local _str variable and moves that result back into the variable whose name was passed into our function as an argument. Here we have another shell limitation to get around. The dereferencing directive (the exclamation point) we used on LINE 40 is only valid on the right side of an assignment. The left side of an assignment must be an actual variable name &#8211; not a varvar. To avoid having to assign the results to a hard-coded global variable, we need a way to assign our results back to the original variable name held in our varvar,\u00a0<\/span><span style=\"font-size: 14px; color: #0c71c3; font-family: 'Roboto Mono';\">_varName<\/span><span style=\"font-size: 14px;\">.\u00a0<\/span><\/p>\n<p><span style=\"font-size: 14px;\">The solution is to use the <\/span><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-weight: normal;\">eval<\/span><span style=\"font-size: 14px;\"> command. The eval command basically takes the string you pass to it and executes it as if you had typed it on a command line. This allows us to use our varvar on the left side of an assignment because the shell interpreter will\u00a0<em>expand<\/em> the varvar to its contents (as it does all variables) and so allows us to assign the results to the original variable. To better understand this, let&#8217;s say our function was invoked by passing in the variable named <span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-weight: normal;\">scriptArg01<\/span> that has a value of &#8221; Hello World &#8221; (note the leading and trailing spaces). \u00a0When our function gets down to LINE 44, the <span style=\"color: #0c71c3;\">eval<\/span> command results in<\/span><\/p>\n<p><span style=\"font-family: 'Roboto Mono'; font-weight: normal; color: #0c71c3;\">$_varName=&#8221;&#8216;${_str}'&#8221;<\/span>\u00a0 being expanded to actually execute <span style=\"font-family: 'Roboto Mono'; font-weight: normal; color: #0c71c3;\">scriptArg01=&#8217;Hello World&#8217;<\/span><\/p>\n<p>Thus, our goal of a reusable function to trim leading and trailing whitespace is realized. Anywhere in our scripts, we can ensure arguments or data that originates outside of our application&#8217;s control is clean of any carriage returns, line feeds, or tabs with a single, simple line of code:<\/p>\n<p><span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-weight: normal;\">trim scriptArg01<\/span><\/p>\n<p>That&#8217;s it! \u00a0Before invoking the function, <span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-weight: normal;\">scriptArg01<\/span> might contain <span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-weight: normal;\">&#8221; hello world &#8220;<\/span> but after invoking that one line of code, it now contains <span style=\"color: #0c71c3; font-family: 'Roboto Mono'; font-weight: normal;\">&#8220;hello world&#8221;<\/span>. \u00a0In our sample program, we output the result with an echo statement <strong><span style=\"color: #e02b20;\">(e)<\/span><\/strong>. We sandwich the value between two pipe symbols just so that it is easier to see that there is no leading or trailing whitespace in the result.<\/p>\n<p><span style=\"font-family: 'Roboto Mono'; font-weight: normal; color: #0c71c3;\"><\/span><\/p>\n<p><span style=\"font-family: 'Roboto Mono'; font-weight: normal; color: #0c71c3;\"><\/span><\/p>\n<p>[\/et_pb_text][et_pb_text _builder_version=&#8221;3.27.4&#8243; text_orientation=&#8221;justify&#8221; text_text_align=&#8221;justify&#8221;]<\/p>\n<h2>Conclusion<\/h2>\n<p>In this article, we dissected a very simple program function called\u00a0<em>trim()<\/em>. Though the function seems simple and small, we covered some crucial scripting concepts such as:\u00a0<\/p>\n<ul>\n<li><em>local<\/em> variables to limit function variables to the local scope<em><\/em><\/li>\n<li><em>creating and dereferencing varvar&#8217;s<\/em> to allow passing any variable to our function without hardcoding<\/li>\n<li><em>command substitution<\/em> in order to assign the results of calling external system utilities like\u00a0<em>sed<\/em> to a variable<\/li>\n<li>using\u00a0<em>echo<\/em> and\u00a0<em>pipe<\/em> to send the contents of a variable to an external command line utility<\/li>\n<li>using\u00a0<em>eval<\/em> to enable us to assign values to the contents of a <em>varvar<\/em>\u00a0<\/li>\n<\/ul>\n<p>In future articles covering other reusable code snippets, we will undoubtedly see these same concepts again in slightly different implementations, but this should just solidify your understanding of them even more. My hope is that just a few such articles will be enough to make you more comfortable with shell scripting and give you the confidence to apply HLL structure and best practices to ensure they are a solid part of your application.<\/p>\n<p><em>\u00a0<\/em><\/p>\n<p>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn about the basics and quirks of shell scripting as we dissect a simple but useful bash function for trimming whitespace from arguments passed into your scripts. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[28],"tags":[31,33,32,34,30,35],"class_list":["post-501","post","type-post","status-publish","format-standard","hentry","category-rich-rijnders-code-snippets","tag-bash","tag-code","tag-script","tag-sh","tag-shell","tag-trim"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>BASH 01: Trim Your Args! - Rich Rijnders<\/title>\n<meta name=\"description\" content=\"You should always trim your arguments or any variable coming from an external source.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/richrijnders.com\/shell-script-trim-args\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"BASH 01: Trim Your Args! - Rich Rijnders\" \/>\n<meta property=\"og:description\" content=\"You should always trim your arguments or any variable coming from an external source.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/richrijnders.com\/shell-script-trim-args\/\" \/>\n<meta property=\"og:site_name\" content=\"Rich Rijnders\" \/>\n<meta property=\"article:published_time\" content=\"2019-08-06T02:00:53+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-12-12T20:32:38+00:00\" \/>\n<meta name=\"author\" content=\"rich\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"rich\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/\"},\"author\":{\"name\":\"rich\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#\\\/schema\\\/person\\\/186c2ab9e139d2ed4065ce4a70046eff\"},\"headline\":\"BASH 01: Trim Your Args!\",\"datePublished\":\"2019-08-06T02:00:53+00:00\",\"dateModified\":\"2020-12-12T20:32:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/\"},\"wordCount\":2577,\"commentCount\":0,\"keywords\":[\"bash\",\"code\",\"script\",\"sh\",\"shell\",\"trim\"],\"articleSection\":[\"Code Snippets\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/\",\"url\":\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/\",\"name\":\"BASH 01: Trim Your Args! - Rich Rijnders\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#website\"},\"datePublished\":\"2019-08-06T02:00:53+00:00\",\"dateModified\":\"2020-12-12T20:32:38+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#\\\/schema\\\/person\\\/186c2ab9e139d2ed4065ce4a70046eff\"},\"description\":\"You should always trim your arguments or any variable coming from an external source.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/shell-script-trim-args\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/richrijnders.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"BASH 01: Trim Your Args!\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#website\",\"url\":\"https:\\\/\\\/richrijnders.com\\\/\",\"name\":\"Rich Rijnders\",\"description\":\"Cloud and SOA Integration Architect\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/richrijnders.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/richrijnders.com\\\/#\\\/schema\\\/person\\\/186c2ab9e139d2ed4065ce4a70046eff\",\"name\":\"rich\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g\",\"caption\":\"rich\"},\"url\":\"https:\\\/\\\/richrijnders.com\\\/profile\\\/rich\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"BASH 01: Trim Your Args! - Rich Rijnders","description":"You should always trim your arguments or any variable coming from an external source.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/richrijnders.com\/shell-script-trim-args\/","og_locale":"en_US","og_type":"article","og_title":"BASH 01: Trim Your Args! - Rich Rijnders","og_description":"You should always trim your arguments or any variable coming from an external source.","og_url":"https:\/\/richrijnders.com\/shell-script-trim-args\/","og_site_name":"Rich Rijnders","article_published_time":"2019-08-06T02:00:53+00:00","article_modified_time":"2020-12-12T20:32:38+00:00","author":"rich","twitter_card":"summary_large_image","twitter_misc":{"Written by":"rich","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/richrijnders.com\/shell-script-trim-args\/#article","isPartOf":{"@id":"https:\/\/richrijnders.com\/shell-script-trim-args\/"},"author":{"name":"rich","@id":"https:\/\/richrijnders.com\/#\/schema\/person\/186c2ab9e139d2ed4065ce4a70046eff"},"headline":"BASH 01: Trim Your Args!","datePublished":"2019-08-06T02:00:53+00:00","dateModified":"2020-12-12T20:32:38+00:00","mainEntityOfPage":{"@id":"https:\/\/richrijnders.com\/shell-script-trim-args\/"},"wordCount":2577,"commentCount":0,"keywords":["bash","code","script","sh","shell","trim"],"articleSection":["Code Snippets"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/richrijnders.com\/shell-script-trim-args\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/richrijnders.com\/shell-script-trim-args\/","url":"https:\/\/richrijnders.com\/shell-script-trim-args\/","name":"BASH 01: Trim Your Args! - Rich Rijnders","isPartOf":{"@id":"https:\/\/richrijnders.com\/#website"},"datePublished":"2019-08-06T02:00:53+00:00","dateModified":"2020-12-12T20:32:38+00:00","author":{"@id":"https:\/\/richrijnders.com\/#\/schema\/person\/186c2ab9e139d2ed4065ce4a70046eff"},"description":"You should always trim your arguments or any variable coming from an external source.","breadcrumb":{"@id":"https:\/\/richrijnders.com\/shell-script-trim-args\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/richrijnders.com\/shell-script-trim-args\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/richrijnders.com\/shell-script-trim-args\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/richrijnders.com\/"},{"@type":"ListItem","position":2,"name":"BASH 01: Trim Your Args!"}]},{"@type":"WebSite","@id":"https:\/\/richrijnders.com\/#website","url":"https:\/\/richrijnders.com\/","name":"Rich Rijnders","description":"Cloud and SOA Integration Architect","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/richrijnders.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/richrijnders.com\/#\/schema\/person\/186c2ab9e139d2ed4065ce4a70046eff","name":"rich","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6bb4ab7390db5599ceab3677366582dcfc4110c702347142e2a71510ad6f2877?s=96&d=mm&r=g","caption":"rich"},"url":"https:\/\/richrijnders.com\/profile\/rich\/"}]}},"_links":{"self":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts\/501","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/comments?post=501"}],"version-history":[{"count":3,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts\/501\/revisions"}],"predecessor-version":[{"id":782,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/posts\/501\/revisions\/782"}],"wp:attachment":[{"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/media?parent=501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/categories?post=501"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/richrijnders.com\/rest\/wp\/v2\/tags?post=501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}