Live data from Hacker News

The Bash Hackers Wiki

wiki.bash-hackers.org

71–80 of 89 posts

Re: The Bash Hackers Wiki

#71

I clicked the config article and it reminded me of 2 major pet peeves: 1) No good way to store config values, nor ones that can be shared with other languages. I might have a set of python applications running in the cloud and a shell script to deploy them, and guess what, I'd like them to share the same config, so I don't have to keep to update resource names in 2 places. 2) No simple way of templating files. A scri…

1) There's a few ways you could skin this proverbial cat:

option 1:

A bit python specific but you can use python-dotenv[1] for Python; and `source` that file in bash for shell support.

option 2:

Alternatively you could just pass environmental variables between applications (that's kind of the point of them).

option 3:

You could still use a dot env file and import that in other languages as TOML. This is a really nasty hacky way of doing things though because you'd need to read that file in, then prefix a key at the start of the file (eg "[vars]") to adhere to the TOML standard before you could run it through a TOML parser. I wouldn't personally recommend this approach but it would work as a lazy solution.

2) Sure there is, `envsubst`[2]

hello.tmpl:

    This is an exmaple
    Hello, ${HELLO_NAME}!
hello.env:

    HELLO_NAME="wodenokoto"
hello.sh:

    #!/bin/sh

    source hello.env
    envsubst  hello.txt
Run hello.sh and it will create a file called hello.txt:

    This is an exmaple
    Hello, wodenokoto!
One caveat is that this is part of the gettext package which doesn't always ship with every distro. But it's a pretty small package (small enough that I don't have any issue installing it into a docker container for one CI pipeline).

[1] https://pypi.org/project/python-dotenv/

[2] https://linux.die.net/man/1/envsubst

Re: The Bash Hackers Wiki

#72

It seems like there is potential for making bash faster. 1. JIT compilation, caching and invalidating on updated source files 3. Rearchitecting similar a-la busybox all of coreutils, sharutils, grep, awk and sed as internal components to avoid forking as much as possible. Tool symlinks back to itself for compatibility. 4. Rearchitecting to simulate sub-shells with threads and local contexts, rather than globals/singu…

Hi, murex author here. Murex is not a POSIX compliant shell but there are some lessons I've learned developing murex which relate to your points:

1. I do this in murex but actually the performance improvement barely registers in benchmarks because that's not where the real bottleneck is. It's forking and it's passing data via standard streams (stdout et al) rather than sharing memory. There's lots of expensive syscalls to do stuff that you wouldn't need to do in a monolithic service. It's also worth noting that shell scripting is designed to be a highly dynamic language - even command names can be variables(!) - so there is a limit to just how much up-front compilation and caching you do (at least if you want to retain POSIX compatibility).

2. No 2?

3. I also do this to some extent in murex too, except it's not coreutils but rather a set of additional utils specific for more complex data wrangling (JSON, YAML, TOML, CSV, etc). Unfortunately it comes with a set of additional complexities, any of which are deal breakers:

i) If you don't fork then processes don't register PIDs so you can't easily kill a long running process or command run in error. To get around this in murex I had to create a new, separate, function list. This list only includes processes launched from murex but it has both external files (awk et al) as well as builtins. This works for murex because murex isn't going for POSIX compatibility but this would never fly with Bash because you then need to train users to use different `kill`, `ps`, etc commands.

ii) Many users take advantage of job control, which is where you can stop, resume and background already running processes. This works via signals (like SIGINT which you'd be familiar with) and is controlled by UNIX/Linux and not the shell. To get this working with non-forked builtins takes a hell of a lot of hacking and, once again, breaks POSIX compatibility. In fact I ended up removing support for SIGSTSP from murex builtins because it wasn't reliable (though I do plan on adding it again at some point). I also have a bug where external commands don't get sent a SIGTTIN (signal to tell background processes to pause if they're reading from stdin) and that's largely due to some of the hacks I've made regarding your first point.

iii) re-implementing coreutils is non-trivial. In fact calling it "non-trivial" is a massively understatement. And that's without touching the other utils you've highlighted. This effort alone is enough to be a deal breaker without taking into account i and ii.

The reason busybox works is because it's a subset of coreutils. In fact busybox can be a little jarring at times because it is missing so many common flags. However it does just enough to be a useful emergency / embedded shell.

4. This is how murex approaches sub-shells but you're still limited by the caching problems (raised to point 1) plus the forking requirements (addressed in point 3) in terms of just how much additional performance it will squeeze. However out of all the points you have discussed, this is the easiest to implement.

It's also worth noting that fork-bombs (or equivalent exploits) will always be possible as long as your code has functions. Removing sub-shells wouldn't prevent someone from writing a self-referencing function.

Re: The Bash Hackers Wiki

#73
post #9

Earlier quoted context omitted.

Bash was the first scripting language I became “good” in too! The skill seems to be regularly devalued in this community, and there is no surprise why (what is collaboration and maintenance for $500). However, it’s hard to ignore why bash masters are born in the first place if better tools exist - shouldn’t the best tool win in the long run? My take is lone wolf hackers working in corporate /_/nix constrained environ…

I love Python, I am a Python trainer and wrote an into book on it. But few years ago, I finally learnt how to use shell and it blew my mind. With a single command, I can split a really large files in 100 based on a particular column or I can aggregate and do whatever I want with a few piped commands, preview any file with sed '3p' file Sure. I do not write 100lines of awk code, but I believe I have started utilizing…

Every language has its place.

I have a workflow I maintain, it takes an image from a file path or a url, converts the image to 2-bit color, adds control codes, and sends the job to the printer - and there were two other utilities did various calibration options for the printer.

So, originally it was written in python2, and used an IPP library that didnt make the leap to python3, so I ported the 'core' (downloading the image, and processing it, and adding the needed control codes) part of the job to python3, and then wrote a bash wrapper to run this script, and pipe the output to lp, it also uses $PIPESTATUS to provide intelligent error codes back to the calling application.

When I approached this, I realized that I could have ported the whole thing to bash, but the more I thought about it I realized it'd probably have greater overhead. First I'd have to run the script, then curl, then next imagemagick (which has its own issues), then insert the formatting around the image, and then run lp. I looked at it and figured python has lower overhead to do all of these things, as everything but the image handling is part of the python standard library.

There were two other scripts however, that all they do is output a bunch of strings, and send them to be printed, these were also python2 and used IPP, these however I just reimplemented in bash, and send the jobs directly to cups.

My attitude is use whatever language you feel comfortable with to accomplish the task, you can do serious programming in bash - people are incredulous at this, but the basic unix toolset is so powerful, you can do almost anything with it.

Re: The Bash Hackers Wiki

#74
post #46
post #17

Earlier quoted context omitted.

That's what Oil is, except it also runs bash scripts and lets you upgrade seamlessly. That is, bin/oil is the same as bin/osh with a bunch of shell options on, including 'shopt -s simple_word_eval' which eliminates a lot of the quoting hassles. You can try it now, but some things will be cut out after optimizing the prototype interpreter (in the name of time): You Can Now Try the Oil Language http://www.oilshell.org/…

> Python 3 and Perl 6/Raku are worse for shell-like tasks than their predecessors! Mainly because of startup time and the string abstaction Startup time can always be better, agree. But full support for Unicode is needed in this day and age, and that brings overhead, whichever way you do that, and especially so if you want to do it 100% correctly. If you're still living in an ASCII world, then by all means, go for it…

Oil has better Unicode support than Python 2 or 3 for shell-like tasks, because of the way file systems, libc, and the kernel work.

Explained here:

http://www.oilshell.org/blog/2018/03/04.html#faq

which links:

http://lucumr.pocoo.org/2014/1/9/ucs-vs-utf8/ (by Armin Ronacher)

The summary is that there are two kinds of Unicode support:

- UTF-8 based: Go, Rust, and Oil (and Perl 5 it seems, not sure about Raku)

- array-of-codepoint based: bash/zsh/libc, Python, Java, JavaScript, Windows (JavaScript notably requires surrogate pairs, Python used to have build time configuration, now has complex storage heuristics, etc.)

This isn't a theoretical problem -- the Unicode problems in the other comment thread I linked are real and show up in practice.

Re: The Bash Hackers Wiki

#75
post #63

Earlier quoted context omitted.

Balderdash and hokum. z=1 ; while test ${z} -lt 4 ; do a=${RANDOM:1:3} ; dd if=/dev/urandom count=12 bs=4 of=${a} && b=$(cat ${a}) && echo ${b:$(expr 1 + ${RANDOM} % 4):12} ; ((z++)); done You have one tool that you know well. I have thousands of tools that I've learned daily and I wrap with a bash script..except when I need python/tcl or C. Most of what I do in python/tcl/C is truly complicated, needs to be fast or…

What's the point of not importing a library/module? It's not like cheating or something.

Eh. Pros and cons.

I think most people are spoiled by being able to install anything; I work in a locked down environment and getting anything non-sanctioned in is very difficult, and the sanctioning process is tedious if nothing else.

That, and the fact that libraries are evolving- which is why we end up with horrible things like package/library version pinning.

Re: The Bash Hackers Wiki

#76
post #75
post #63

Earlier quoted context omitted.

What's the point of not importing a library/module? It's not like cheating or something.

Eh. Pros and cons. I think most people are spoiled by being able to install anything; I work in a locked down environment and getting anything non-sanctioned in is very difficult, and the sanctioning process is tedious if nothing else. That, and the fact that libraries are evolving- which is why we end up with horrible things like package/library version pinning.

Sure, but we're talking (with the problem at hand) about Python standard libraries that get shipped with the Python distribution and not some NPM or pip universe.

For instance the "os" module has an "urandom" function that does essentially the same as the "dd" in the bash script. Of course you could also read from the device so you wouldn't need to import "os". You would need to import "random" to get access to the random number generator, though, but it's still part of the standard library.

Re: The Bash Hackers Wiki

#77
post #71

I clicked the config article and it reminded me of 2 major pet peeves: 1) No good way to store config values, nor ones that can be shared with other languages. I might have a set of python applications running in the cloud and a shell script to deploy them, and guess what, I'd like them to share the same config, so I don't have to keep to update resource names in 2 places. 2) No simple way of templating files. A scri…

1) There's a few ways you could skin this proverbial cat: option 1: A bit python specific but you can use python-dotenv[1] for Python; and `source` that file in bash for shell support. option 2: Alternatively you could just pass environmental variables between applications (that's kind of the point of them). option 3: You could still use a dot env file and import that in other languages as TOML. This is a really nast…

> just pass environmental variables between applications

That would require me to 1) somehow ensure that shell is sourcing the the environment variables from a file, and 2) we are back to all the hackery mentioned in the article [1]

[1] https://wiki.bash-hackers.org/howto/conffile

Re: The Bash Hackers Wiki

#78
post #74
post #46

Earlier quoted context omitted.

> Python 3 and Perl 6/Raku are worse for shell-like tasks than their predecessors! Mainly because of startup time and the string abstaction Startup time can always be better, agree. But full support for Unicode is needed in this day and age, and that brings overhead, whichever way you do that, and especially so if you want to do it 100% correctly. If you're still living in an ASCII world, then by all means, go for it…

Oil has better Unicode support than Python 2 or 3 for shell-like tasks, because of the way file systems, libc, and the kernel work. Explained here: http://www.oilshell.org/blog/2018/03/04.html#faq which links: http://lucumr.pocoo.org/2014/1/9/ucs-vs-utf8/ (by Armin Ronacher) The summary is that there are two kinds of Unicode support: - UTF-8 based: Go, Rust, and Oil (and Perl 5 it seems, not sure about Raku) - array-…

Unicode support of Raku is grapheme based (NFG or Normalization Form Grapheme). The unicode theory: https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundarie... , about the implementation: https://6guts.wordpress.com/2015/04/12/this-week-unicode-nor...

Re: The Bash Hackers Wiki

#79
post #71

Earlier quoted context omitted.

1) There's a few ways you could skin this proverbial cat: option 1: A bit python specific but you can use python-dotenv[1] for Python; and `source` that file in bash for shell support. option 2: Alternatively you could just pass environmental variables between applications (that's kind of the point of them). option 3: You could still use a dot env file and import that in other languages as TOML. This is a really nast…

> just pass environmental variables between applications That would require me to 1) somehow ensure that shell is sourcing the the environment variables from a file, and 2) we are back to all the hackery mentioned in the article [1] [1] https://wiki.bash-hackers.org/howto/conffile

You don't need a shell script to initialise an application with specific environmental variables. systemd and docker will both do this (and both supports the same env file too). AWS lambda supports environmental variables, so does most CI/CD solutions. It's a pretty standard way to do things in UNIX/Linux. In fact if you're having to resort to "hacks" to get environmental variables loaded then that might be a symptom of a bigger problem with your orchestration rather than an issue with Bash / Python.

Also that was just one of three options I listed; and there will be a plethora of other alternatives I've not mentioned too.

Re: The Bash Hackers Wiki

#80
post #40
post #17

Earlier quoted context omitted.

That's what Oil is, except it also runs bash scripts and lets you upgrade seamlessly. That is, bin/oil is the same as bin/osh with a bunch of shell options on, including 'shopt -s simple_word_eval' which eliminates a lot of the quoting hassles. You can try it now, but some things will be cut out after optimizing the prototype interpreter (in the name of time): You Can Now Try the Oil Language http://www.oilshell.org/…

Once Oil has better documentation I'll probably give it a try. The documents outlined in "Docs I Want to Write" seem promising and are still only visible as drafts in Zulip which requires logging in.

That's fair, in the meantime this post gives some more examples:

http://www.oilshell.org/blog/2020/01/simplest-explanation.ht...

as well as other posts tagged #oil-language:

http://www.oilshell.org/blog/tags.html?tag=oil-language#oil-...

Post reply on HN