{"id":2223,"date":"2022-03-02T06:26:21","date_gmt":"2022-03-02T06:26:21","guid":{"rendered":"https:\/\/blog.samarthya.me\/wps\/?p=2223"},"modified":"2022-03-02T06:27:41","modified_gmt":"2022-03-02T06:27:41","slug":"bash-named-reference","status":"publish","type":"post","link":"https:\/\/blog.samarthya.me\/wps\/2022\/03\/02\/bash-named-reference\/","title":{"rendered":"Bash: Named Reference"},"content":{"rendered":"\n<p>Bash is different world. Powerful, simple, elegant and complex all at the same time. Recently while trying to reduce the burden of repetitive code, I was trying to check what can be done to use references in Bash (something like pointers) and it was an interesting problem that I enjoyed solving.<\/p>\n\n\n\n<div class=\"wp-block-snow-monkey-blocks-balloon smb-balloon smb-balloon--reverse wp-block-snow-monkey-blocks-balloon-is-layout-constrained\"><div class=\"smb-balloon__person\"><div class=\"smb-balloon__figure\"><img decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-150x150.webp\" alt=\"\" class=\"wp-image-2226\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-150x150.webp 150w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-300x300.webp 300w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash.webp 512w\" sizes=\"(max-width: 150px) 100vw, 150px\" \/><\/div><div class=\"smb-balloon__name\">Bash<\/div><\/div><div class=\"smb-balloon__body is-layout-constrained wp-block-balloon-is-layout-constrained\"><p>The \u2018<samp>$<\/samp>\u2019 character introduces parameter expansion, command substitution, or arithmetic expansion. The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name.<\/p><\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><code>declare -n &lt;name&gt;<\/code><\/h2>\n\n\n\n<p>In bash version 5.1.8 (<code>bash --version<\/code>) I could see that you can utilize the <code>local -n<\/code> or <code>declare -n<\/code> to help you define a named reference but in the version before like <code>4.2.46<\/code> there was no support for named reference<\/p>\n\n\n\n<pre class=\"wp-block-code has-pale-cyan-blue-background-color has-background\"><code>&gt; bash --version\nGNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)\nCopyright (C) 2011 Free Software Foundation, Inc.\nLicense GPLv3+: GNU GPL version 3 or later &lt;http:\/\/gnu.org\/licenses\/gpl.html&gt;\n\nThis is free software; you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitted by law.<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code has-pale-pink-background-color has-background\"><code>declare: declare &#91;-aAfFgilrtux] &#91;-p] &#91;name&#91;=value] ...]\n    Set variable values and attributes.\n    \n    Declare variables and give them attributes.  If no NAMEs are given,\n    display the attributes and values of all variables.\n    \n    Options:\n      -f\trestrict action or display to function names and definitions\n      -F\trestrict display to function names only (plus line number and\n    \tsource file when debugging)\n      -g\tcreate global variables when used in a shell function; otherwise\n    \tignored\n      -p\tdisplay the attributes and value of each NAME\n    \n    Options which set attributes:\n      -a\tto make NAMEs indexed arrays (if supported)\n      -A\tto make NAMEs associative arrays (if supported)\n      -i\tto make NAMEs have the `integer' attribute\n      -l\tto convert NAMEs to lower case on assignment\n      -r\tto make NAMEs readonly\n      -t\tto make NAMEs have the `trace' attribute\n      -u\tto convert NAMEs to upper case on assignment\n      -x\tto make NAMEs export\n    \n    Using `+' instead of `-' turns off the given attribute.\n    \n    Variables with the integer attribute have arithmetic evaluation (see\n    the `let' command) performed when the variable is assigned a value.\n    \n    When used in a function, `declare' makes NAMEs local, as with the `local'\n    command.  The `-g' option suppresses this behavior.\n    \n    Exit Status:\n    Returns success unless an invalid option is supplied or an error occurs.<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example of <code>-n<\/code><\/h2>\n\n\n\n<p>I defined a function set_var that takes one argument ( a variable name) and sets the value to &#8216;<code>NewValue<\/code>&#8216; as shown below.<\/p>\n\n\n\n<div class=\"wp-block-snow-monkey-blocks-balloon smb-balloon wp-block-snow-monkey-blocks-balloon-is-layout-constrained\"><div class=\"smb-balloon__person\"><div class=\"smb-balloon__figure\"><img decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-150x150.webp\" alt=\"\" class=\"wp-image-2226\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-150x150.webp 150w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-300x300.webp 300w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash.webp 512w\" sizes=\"(max-width: 150px) 100vw, 150px\" \/><\/div><div class=\"smb-balloon__name\">Bash<\/div><\/div><div class=\"smb-balloon__body is-layout-constrained wp-block-balloon-is-layout-constrained\"><p>A variable can be assigned the&nbsp;<var>nameref<\/var>&nbsp;attribute using the&nbsp;<samp>-n<\/samp>&nbsp;option to the&nbsp;<code>declare<\/code>&nbsp;or&nbsp;<code>local<\/code>&nbsp;builtin commands (see&nbsp;<a href=\"https:\/\/www.gnu.org\/software\/bash\/manual\/bash.html#Bash-Builtins\">Bash Builtins<\/a>) to create a&nbsp;<var>nameref<\/var>, or a reference to another variable.&nbsp;<\/p><\/div><\/div>\n\n\n\n<pre class=\"wp-block-code has-pale-ocean-gradient-background has-background\"><code>#!\/bin\/bash\n\nfunction set_var {\n    local -n myVar=$1\n    echo \" before: $myVar\"\n    myVar=\"New Value\"\n    echo \" After: ${myVar}\"\n}\n\n\n(( $# &lt; 1 )) &amp;&amp; (echo \" Usage: ${0##*\/} &lt;any value&gt;\")  &amp;&amp; exit 1;\nOLDVALUE=$1\necho \" Before function invoke: OLDVALUE := ${OLDVALUE}\"\necho \" Invoking the function change\"\nset_var OLDVALUE\necho \" After function invoke: OLDVALUE := ${OLDVALUE}\"<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example of without <code>-n<\/code><\/h2>\n\n\n\n<p>If I use the code above in the older bash version where <code>-n<\/code> is not supported.<\/p>\n\n\n\n<pre class=\"wp-block-code has-blush-light-purple-gradient-background has-background\"><code>&gt; .\/script.sh old\n Before function invoke: OLDVALUE := old\n Invoking the function change\n.\/script.sh: line 4: local: -n: invalid option\nlocal: usage: local &#91;option] name&#91;=value] ...\n before: \n After: New Value\n After function invoke: OLDVALUE := old<\/code><\/pre>\n\n\n\n<p>The basic form of parameter expansion is ${<var>parameter<\/var>}.<\/p>\n\n\n\n<div class=\"wp-block-snow-monkey-blocks-balloon smb-balloon wp-block-snow-monkey-blocks-balloon-is-layout-constrained\"><div class=\"smb-balloon__person\"><div class=\"smb-balloon__figure\"><img decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-150x150.webp\" alt=\"\" class=\"wp-image-2226\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-150x150.webp 150w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash-300x300.webp 300w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/03\/bash.webp 512w\" sizes=\"(max-width: 150px) 100vw, 150px\" \/><\/div><div class=\"smb-balloon__name\">Bash<\/div><\/div><div class=\"smb-balloon__body is-layout-constrained wp-block-balloon-is-layout-constrained\"><p>If the first character of&nbsp;<var>parameter<\/var>&nbsp;is an exclamation point (!), and&nbsp;<var>parameter<\/var>&nbsp;is not a&nbsp;<var>nameref<\/var>, it introduces a level of indirection.&nbsp;<\/p><\/div><\/div>\n\n\n\n<div class=\"wp-block-snow-monkey-blocks-balloon smb-balloon smb-balloon--reverse wp-block-snow-monkey-blocks-balloon-is-layout-constrained\"><div class=\"smb-balloon__person\"><div class=\"smb-balloon__figure\"><img decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/01\/cropped-IMG-20170114-WA0018-150x150.jpg\" alt=\"\" class=\"wp-image-1915\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/01\/cropped-IMG-20170114-WA0018-150x150.jpg 150w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/01\/cropped-IMG-20170114-WA0018-150x150@2x.jpg 300w\" sizes=\"(max-width: 150px) 100vw, 150px\" \/><\/div><div class=\"smb-balloon__name\">Saurabh<\/div><\/div><div class=\"smb-balloon__body is-layout-constrained wp-block-balloon-is-layout-constrained\"><p>Read more about it in the official documentation <a href=\"https:\/\/www.gnu.org\/software\/bash\/manual\/bash.html\" data-type=\"URL\" data-id=\"https:\/\/www.gnu.org\/software\/bash\/manual\/bash.html\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a><\/p><\/div><\/div>\n\n\n\n<p>Let&#8217;s improvise and see what we can do<\/p>\n\n\n\n<pre class=\"wp-block-code has-pale-cyan-blue-background-color has-background\"><code>#!\/bin\/bash\n\nfunction set_var {\n    local myVar=$1\n    echo \" before: ${!myVar}\"\n    eval $myVar='abcdef'\n    echo \" After: ${!myVar}\"\n}\n\n\n(( $# &lt; 1 )) &amp;&amp; (echo \" Usage: ${0##*\/} &lt;any value&gt;\")  &amp;&amp; exit 1;\necho \" Parameter:  $*\"\nOLDVALUE=$1\necho \" Before function invoke: OLDVALUE := ${OLDVALUE}\"\necho \" Invoking the function change\"\nset_var OLDVALUE\necho \" After function invoke: OLDVALUE := ${OLDVALUE}\"<\/code><\/pre>\n\n\n\n<div class=\"wp-block-snow-monkey-blocks-balloon smb-balloon smb-balloon--reverse wp-block-snow-monkey-blocks-balloon-is-layout-constrained\"><div class=\"smb-balloon__person\"><div class=\"smb-balloon__figure\"><img decoding=\"async\" width=\"150\" height=\"150\" src=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/01\/cropped-IMG-20170114-WA0018-150x150.jpg\" alt=\"\" class=\"wp-image-1915\" srcset=\"https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/01\/cropped-IMG-20170114-WA0018-150x150.jpg 150w, https:\/\/blog.samarthya.me\/wps\/wp-content\/uploads\/2022\/01\/cropped-IMG-20170114-WA0018-150x150@2x.jpg 300w\" sizes=\"(max-width: 150px) 100vw, 150px\" \/><\/div><div class=\"smb-balloon__name\">Saurabh<\/div><\/div><div class=\"smb-balloon__body is-layout-constrained wp-block-balloon-is-layout-constrained\"><p>Indirection: The expansion&nbsp;<code>${!<var>prefix<\/var>*}<\/code>&nbsp;expansion, which expands to the names of all shell variables whose names begin with&nbsp;<var>prefix<\/var>, is available.<\/p><\/div><\/div>\n\n\n\n<pre class=\"wp-block-code\"><code> &gt; .\/script.sh old\n Parameter:  old\n Before function invoke: OLDVALUE := old\n Invoking the function change\n before: old\n After: abcdef\n After function invoke: OLDVALUE := abcdef<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Bash is different world. Powerful, simple, elegant and complex all at the same time. Recently while trying to reduce the burden of repetitive code, I was trying to check what can be done to use references in Bash (something like pointers) and it was an interesting problem that I enjoyed solving. Bash The \u2018$\u2019 character [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2226,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"image","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[34,239],"tags":[245,248,112,249],"class_list":["post-2223","post","type-post","status-publish","format-image","has-post-thumbnail","hentry","category-technical","category-technical-2","tag-bash","tag-indirect","tag-linux","tag-nameref","post_format-post-format-image"],"_links":{"self":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/2223","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/comments?post=2223"}],"version-history":[{"count":0,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/posts\/2223\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media\/2226"}],"wp:attachment":[{"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/media?parent=2223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/categories?post=2223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.samarthya.me\/wps\/wp-json\/wp\/v2\/tags?post=2223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}