Bash function names can be almost anything
blog.dnmfarrell.com
blog.dnmfarrell.com
:(){ :|:& };:
Turns into a less mysterious: bomb() {
bomb | bomb &
}
bomb
I started a booklet with some of these tricks and explanations in https://raimonster.com/scripting-field-guide/, in case anyone wants to give feedback (or PRs), it'd be much appreciated.This limit isn't set by default in most distributions, but does exist.
It would still crash the bombed shell but the server itself would be safe and a manual kill signal could be send to the bombing thread.
rethoric -> rhetoric
1 off -> one-off
ment -> meant
low hanging -> low-hanging
flag you many of those ticking bombs -> flag many of those ticking bombs for you
No matter which editor you are using, but you -> No matter which editor you are using, you
The best example in that StackOverflow is this one: -> [maybe delete this line? or write something else. I don't know its purpose, it makes no sense.]
a bunch of elements from one go -> a bunch of elements in one go
functions in shell -> shell functions
using user's input -> using user input/using the user's input
you can unset -> You can unset
lots of code you see around rely on -> lots of code you see around relies on
to thinking on creating -> to thinking about creating
foo() {
foo() { true; }
echo "This bit will only be executed on the first foo call"
}
(The `true;` body is needed by some shells, e.g. bash, and not others, e.g. zsh.) function echo { echo "$@"; }
Oops don't do that, it will recurse until the process is killed. But if you do successfully redefine a builtin command, you can call the original with command. So this is fine: function echo { command echo "$@"; }
Unless you also redefine the command command, then you're really screwed.And there can rarely be fun side effects.
As an example, I alias "cat" to run "bat", which pretty-prints the output. If I don't want the pretty-printed output, I can "command cat foo.txt" and it will call the "real" cat.
~ $ alias true='echo alias'
~ $ true
alias
~ $ \true
~ $ 'true'
~ $ tr'u'e
~ $"\ls" is the same as "command ls" and will run ls ignoring any functions or aliases that normally replace it.
The `=` prefix in zsh works, but is a different beast entirely. The backslash trick will simply stop the command parser from expanding the alias, while the equals prefix will expand to the full path of the given command at parsing time. For example:
$ print -l =cat =bat
/usr/bin/cat
/usr/bin/bat
While it is a trivial difference in your use case, it can be useful in itself; You could use `ldd =zsh` instead of needing to provide the full path, or `dpkg -S =make` to search for /usr/bin/make(or whatever) instead of returning results of files with the string make anywhere in the name.It is a default setting for the expansion system(only when in zsh mode), but can be disabled with `unsetopt equals` if you dislike it. Gory details in zshexpn(1) and zshoptions(1).
vim =audioctl
Expands to vim /home/myusername/bin/audioctl (trace format)
This causes a line to be printed every time FORMAT is called, showing the arguments it was called with. Well, FORMAT is Lisp's printf -- it's used everywhere, including by TRACE. Oops!!! Time for Ctrl-Meta-Ctrl-Meta-Rubout! (That was the key sequence for an immediate reboot. Interesting how it prefigured the IBM PC's Ctrl-Alt-Delete.)That is not what POSIX mode is for. POSIX mode is to let POSIX scripts work, not to let non-POSIX scripts fail. The latter is done only insofar as it is necessary to achieve the former, so POSIX mode still leaves plenty of extensions enabled, which is fine for its intended use.
for, while and until are also compound commands, so they also can be used as function body directly without braces, but there’s no practical use for that, really.
> What is this useful for?
I think it makes sense because bash function invocation is the same as calling an external program which name is only restricted by what is allowed as a file-path.
And lots of people use Nix - and write a lot of bash.
It is still a work-in-progress project and the documentation on the website is not up-to-date, but I think we are working on the same problem ;-)
If you want to run probably all the code I have written, you can run the test-suite like:
curl -fsL https://mdl.sh/development/tools/run-all-tests/run-all-tests-0.9.16.sh | sh
A total run-time of 8 Minutes is normal and there is little output in the beginning.The code is available on Github[2].
[1]: https://module.sh
Also, code without comments and documentation is useless, because developer must invest some time into browsing and understanding of your code first, but, often, it faster to rewrite code from scratch instead.
Also, you forget to include a license for your code, so nobody can use your code for any purpose.
I like the idea of downloading of modules at demand, with verification of integrity. I'm looking to implement something like that for my project too, but I'm afraid that I will not be able to implement it securely enough.
Yes, there are certainly some modules which lack comments. On the other hand, there is at least one module which has its own readme to explain the code:
https://github.com/arendtio/mdl.sh/tree/master/development/d...
Regarding the security: As said, I am targeting POSIX and as far as I know, the only checksum tool available is cksum. This is borderline insecure but catches transmission errors at least. However, if you do not have such strict requirements you can easily use something like sha256sum. In fact, my module allows to use alternative checksum tools but uses cksum if nothing else is specified (because it is better than nothing and always available).
Just to give one example: The topic of errexit aka `set -e`.
In the beginning, I thought it should be an easy decision and since programs are supposed to be reliable, they should terminate in case of an error. So I added `set -e` to all my scripts. However, later I learned, that if you call a function from within a condition, the function is executed without `set -e` even if the function itself sets the option. Since then, I am unsure if it is better to have a function that 'sometimes exits' when it comes across an error or 'never exists' when it comes across an error, because 'always exists' when it comes across an error does not exist.
[0]: https://nickjanetakis.com/blog/replacing-make-with-a-shell-s...