Live data from Hacker News

Pure Bash Bible

github.com

251–258 of 258 posts

Re: Pure Bash Bible

#252

I have a personal dislike for regexes and non human readable code, it gives maintenance headache. It's why I avoid shell scripts as much as possible. The first example is not human readable, if the name of the function is a lie, I have no idea what this piece of code do : trim_string() { : "${1#"${1%%[![:space:]]*}"}" : "${_%"${_##*[![:space:]]}"}" printf '%s\n' "$_" }

I only got to the first example and had a hard time deciding if the article was satire or not.

Let's use bash instead of a real programming language! It is super convenient! To do super fundamental things like trimming strings you just have to implement your own function with 40+ non-ASCII characters in a row! That example makes regexps seem like human readable and god knows if it is even correct or works portably across different versions of bash.

To be fair the article assumes you are first in bash and want to avoid launching subprocesses but for any production scripting that is the wrong hypothesis to begin with. A better approach would be to not start inside bash at all. Just do your scripting in a higher level language where basic ABC stuff like string, list, number and error handling are already there for you. Even if that trim_string function and everything else from the article would be provided in some bash-bible-std-lib it wouldn't even come close to what's available in say Python for example, and you still have to wrestle the syntax and other obscurities like -a (or -e) meaning file exists.

While there are some good examples in there if you are stuck in bash, this article was more of a 100 reasons not to use bash to me.

Re: Pure Bash Bible

#253
post #41

Earlier quoted context omitted.

> I've learned a lot of tricks and I'm very tempted to write a second "bible" with snippets that are supported in all POSIX shells. That could be potentially even more interesting than a bash-specific one (as it is harder to get it right -- bash can be figured out out of the single reference, anything "portable" has many dependencies).

I've started working on it here: https://github.com/dylanaraps/pure-sh-bible

I see you already made progress there! Congratulations!

Re: Pure Bash Bible

#254
post #195

Earlier quoted context omitted.

It is a neat academic exercise to find these but I think that's sort of the point - why? If you're building something that multiple folks will be reading and using just call out to external processes and make it easier to follow what's going on. It's neat to know how to do these things, but they're honestly a bit of a security hole because a large portion of folks using them will never comprehend the why and how and…

Useful in small embedded. Add twelve lines to a boot script, or bring in several new executables into /bin? There are resource constraints even in large-ish embedded. Your main file system may live in a decent amount of flash space, but when the kernel is booting, it uses a tiny file system in RAM, which is pulled out of an initramfs image. There is a shell there with scripts. The partition for storing the kernel ima…

Wouldn't a compiled binary be smaller and faster than an interpreted language? Assuming stdlib is already loaded.

Re: Pure Bash Bible

#255
post #58

Earlier quoted context omitted.

Don't see why it "doesn't scale well", the overhead is roughly constant: use the stdout of one program as the input of the next.

That's not as easy as cat something | grep "this" | cut -f 1 | sed -e 's/.../.../' You end up writing too much code, it's very verbose. Some times symbols are what you want. In fact the biggest progress in the growth of Math happened when they tossed out doing math with words and bought in symbols.

You forgot setting -e and -o pipefail. In case "something" is missing or can't be read for some other reason, your script will just continue happily without warning.

But oh, if you do set -o pipefail the grep will stop the whole pipeline when none of the lines matches "this". So you have to keep fiddling with ${PIPESTATUS[0]}. And none of pipefail or PIPESTATUS are really portable.

Not so simple after all.

Re: Pure Bash Bible

#256
post #89

Earlier quoted context omitted.

If you pardon the shameless self promotion; I'm working on something just like that: https://github.com/lmorg/murex It currently has: * Proper error handling (eg try and catch blocks) * unit testing and debugging frameworks to help with development and maintainability * data-type aware, including complex types like how CSV, JSON and YAML are all handled as memory structures and thus the same tools can query any struc…

Seems quite similar to Elvish ( https://elv.sh/); have you checked it out?

Sorry, only just seen this comment. Just in case you're still following this thread and interested in a reply:

I'm aware of Elvish and really impressed with what's been built and the traction that has gained. There is definitely some overlap between murex and elvish but also a lot of area's where our shells differ.

I think there is sufficient difference between the two shells to justify their existence.

Re: Pure Bash Bible

#257

Earlier quoted context omitted.

My favourite way to log.. Redirect stdout and stderr ( &> ) into a named pipe ( >() ) running "tee" And get the redirect into the log file as well. `exec &> >(tee ${__DIR}/${DOC_LOCAL}/${LOG_LOCAL})`

Would you mind expanding on this with an example? I'm trying to improve performance of my bash logging

So this line only redirects all script output to a file as well as ensure that that output makes it onto your screen at the same time.

It is unstructured only in the way you allow any running command within your script to dump their output.

I run most commands inside my scripts with `> /dev/null 2>&1` and then rely on exit codes to wrap structured information to be echoed out with this function:

echo_l(){echo;echo '--------';echo "${1}";echo '--------';echo}

Or functions such as this to populate a log:

log_cat(){echo "${1}" >> ${__LOG} }

But the tee named pipe is the winner.

PS. The __DOC_LOCAL and __DIR variables start with these magic variables below. These variables are a life saver and allow easy directory and file manipulation, they kind of setup a top-level context:

# Set magic variables for current file & dir

__DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

__FILE="${__DIR}/$(basename "${BASH_SOURCE[0]}")"

__SCRIPT="$(basename ${__FILE})"

__BASE="$(basename ${__FILE} .sh)"

__ROOT="$(cd "$(dirname "${__DIR}")" && pwd)"

Re: Pure Bash Bible

#258

Earlier quoted context omitted.

Seems quite similar to Elvish ( https://elv.sh/); have you checked it out?

Sorry, only just seen this comment. Just in case you're still following this thread and interested in a reply: I'm aware of Elvish and really impressed with what's been built and the traction that has gained. There is definitely some overlap between murex and elvish but also a lot of area's where our shells differ. I think there is sufficient difference between the two shells to justify their existence.

Oh, definitely. Just thought it was something you should check out and I didn't see it mentioned anywhere.
Post reply on HN