diff options
1 files changed, 29 insertions, 31 deletions
| -rw-r--r-- | src/blog/bash-is-weird/index.du | 60 |
diff --git a/src/blog/bash-is-weird/index.du b/src/blog/bash-is-weird/index.du index 3fbc2cd..2a33dcc 100644 --- a/src/blog/bash-is-weird/index.du +++ b/src/blog/bash-is-weird/index.du @@ -1,65 +1,63 @@ -# BASH is weird +'def title BASH is weird +'def desc Interesting quirks of BASH -'define expected-reading 4 min -'define created 01 May 2023 -'define edited 02 May 2023 -[$pagenav] +# {title} -'footnote parameter-expansion Of course this is just one of the many ways to reference and work with variables. -For very basic stuff, BASH is decently simple and intuitive, for example variables are set with the format [`name=value`] and they're referenced with [`\$name`] [$parameter-expansion]. -However, that changes once you start diving deeper (as I had to do for my [url /talks/linuxgraphy-by-strabo Linuxgraphy by Strabo] presentation). +{pagenav 4 min;01 May 2023;02 May 2023} + +For very basic stuff, BASH is decently simple and intuitive, for example variables are set with the format {` name=value} and they're referenced with {` $name} {fn Of course this is just one of the many ways to reference and work with variables.}. +However, that changes once you start diving deeper (as I had to do for my {url Linuxgraphy by Strabo;/talks/linuxgraphy-by-strabo} presentation). An example which illustrates my point would be: ```bash +'emplace myvar=($(echo A B C)) myvar=1234 -echo $((myvar += 46)) ${myvar[\${myvar:0:1}]} +echo $((myvar += 46)) ${myvar[${myvar:0:1}]} +'endemplace It has 3 things which really bothered me: :ordered -1. The output of [`\$(echo A B C)`] is replaced "literally", and then the whole expression is evaluated. - Meaning, [`myvar=($(echo A B C))`] turns into [`myvar=(A B C)`], which creates an array with those three letters. +1. The output of {` $(echo A B C)} is replaced "literally", and then the whole expression is evaluated. + Meaning, {` myvar=($(echo A B C))} turns into {` myvar=(A B C)}, which creates an array with those three letters. - .p - I thought the "returned" value of [`\$(echo A B C)`] would be the whole string "A B C", so the array would have one element, that string. - However, [`\$()`] isn't really a function, which takes arguments, "creates" commands and returns their output. - It's [url https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html Command [=Substitution=]], the text gets executed and it's output [=replaces=] the [`\$(...)`] itself (slightly reminiscent of [url https://lispcookbook.github.io/cl-cookbook/macros.html LISP macros]). + I thought the "returned" value of {` $(echo A B C)} would be the whole string "A B C", so the array would have one element, that string. + However, {` $()} isn't really a function, which takes arguments, "creates" commands and returns their output. + It's {url Command {b Substitution};https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html}, the text gets executed and it's output {b replaces} the {` $(...)} itself (slightly reminiscent of {url LISP macros;https://lispcookbook.github.io/cl-cookbook/macros.html}). - .p Side note: obviously, the original expected behaviour can happen if we use some quotes: ```bash myvar=("$(echo A B C)") -2. On the second line, [`myvar`] [*becomes*] an integer and then we do an arithmetic operation on it, nothing wrong here. - [`\${parameter:offset:length}`] returns the substring from [`parameter`] from [`offset`] with size [`length`], but we're giving it a "number", so it should either throw some sort of error or return something default, like 0. +2. On the second line, {` myvar} {i becomes} an integer and then we do an arithmetic operation on it, nothing wrong here. + {` $\{parameter:offset:length\}} returns the substring from {` parameter} from {` offset} with size {` length}, but we're giving it a "number", so it should either throw some sort of error or return something default, like 0. However it correctly returns the number 1 (and no, that isn't a default, the number is correctly parsed as a string). - .p This shows that numbers are actually strings too, and numerical operations are just weird string operations. - Contrary to any dynamically-typed language, it's not like the type of a variable is inferred from it's value, [url https://tldp.org/LDP/abs/html/untyped.html there isn't a type at all]! - Which makes everything even more weird, considering you [*can*] [url https://www.gnu.org/software/bash/manual/bash.html#index-declare create variables with a specific type]. + Contrary to any dynamically-typed language, it's not like the type of a variable is inferred from it's value, {url there isn't a type at all;https://tldp.org/LDP/abs/html/untyped.html}! + Which makes everything even more weird, considering you {i can} {url create variables with a specific type;https://www.gnu.org/software/bash/manual/bash.html#index-declare}. -3. Finally, the arguably biggest weirdness of it all, is [`\${myvar[1]}`]. - It doesn't matter how it is represented, at first [`myvar`] was the list of values A, B, C and now it's a number, this should return nothing. - Per contra, the value [`B`] is returned instead! +3. Finally, the arguably biggest weirdness of it all, is {` $\{myvar[1]\}}. + It doesn't matter how it is represented, at first {` myvar} was the list of values A, B, C and now it's a number, this should return nothing. + Per contra, the value {` B} is returned instead! - .p - Via trial and error, we find that our number will be returned when the index is 0, and with index 2 we get [`C`]. + Via trial and error, we find that our number will be returned when the index is 0, and with index 2 we get {` C}. So all variables are arrays, and by default for integer and string operations, the first value is used? - .p - This is strange, but it cannot be the full picture, because [url https://linux.die.net/Bash-Beginners-Guide/sect_10_01.html names have attributes], alongside it's type, a variable (name) can be read-only, but also have the "trace" flag, which only works with functions. + This is strange, but it cannot be the full picture, because {url names have attributes;https://linux.die.net/Bash-Beginners-Guide/sect_10_01.html}, alongside it's type, a variable (name) can be read-only, but also have the "trace" flag, which only works with functions. So, variables and functions are the same "object"? Unfortunately, I couldn't find any definitive information on the topic, so this train of thought will have to be left unresolved. -And this is just one example, more bizarreness can be found with [url https://www.vidarholen.net/contents/blog/?p=25 square brackets] and [url https://mywiki.wooledge.org/BashPitfalls most ok looking code]. -[url https://chrisdone.com/posts/shell-conduit/ Some people] even go as far to say: +And this is just one example, more bizarreness can be found with {url square brackets;https://www.vidarholen.net/contents/blog/?p=25} and {url most ok looking code;https://mywiki.wooledge.org/BashPitfalls}. +{url Some people;https://chrisdone.com/posts/shell-conduit/} even go as far to say: .quote Its syntax is insane, incredibly error prone, its defaults are awful, and it’s not a real big person programming language. -But I believe that is a step too far, [url http://www.binaryphile.com/bash/2018/07/26/approach-bash-like-a-developer-part-1-intro.html there are benefits, especially when approaching it seriously]. +But I believe that is a step too far, {url there are benefits, especially when approaching it seriously;http://www.binaryphile.com/bash/2018/07/26/approach-bash-like-a-developer-part-1-intro.html}. Every language has mind-numbing oddities, some get the out of the way from the start (like BASH), and others much later. + +{footnotes} |