8 ms·
Bash function names can be almost anything
- thunderbong 5y agoWoah! I didn't know about the `command` trick. From the article - 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.
- bombcar 5y agoAnother fun thing is many commands are built in now (like true) but ALSO exist in /bin as an entirely separate program. And there can rarely be fun side effects.
- dredmorbius 5y agoecho is in fact one of these. There's the bash shell built-in and the system executable.
- mfontani 5y ago"command" works also interactively, to call the "real" thing instead of the aliased thing. 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.
- LanternLight83 5y agoI like to escape aliases (ie. using `\vi` when vi is aliased to $EDITOR, but I actually want it), and actually have a special case for bat where I bind ccat to `bat -p --pager=never` for nice, copy-able, and still potentially highlighted output.
- fckthisguy 5y agobat's great! There's an easy way to disable pretty printing too: either use the flag, or pipe to another command.
- deleted 5y ago[deleted]
- stonewareslord 5y agoYou can also bypass aliases by escaping some part of the command ~ $ alias true='echo alias' ~ $ true alias ~ $ \true ~ $ 'true' ~ $ tr'u'e ~ $
- LeoPanthera 5y agoPrefixing a command with a backslash is equivalent to this. "\ls" is the same as "command ls" and will run ls ignoring any functions or aliases that normally replace it.
- forty 5y ago\ls and 'ls' works for avoiding aliases, but from a quick try on termux, doesn't seem to ignore functions.
- mkl 5y agoSame in bash on Linux.
- IronBacon 5y agoOn Zsh there is also '=' as prefix, at least that's what I normally use, don't recall if it's a default setting or the result of a local configuration...
- JNRowe 5y agoPerhaps you already know, but… 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).
- maddyboo 5y agoA cool thing about = is it expands to the full path of the executable, so I often use it to edit the shell scripts that are in my PATH, e.g. vim =audioctl Expands to vim /home/myusername/bin/audioctl
- ScottBurson 5y agoReminds me of the time I was on a Lisp Machine and did (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.)
- haolez 5y agoI love Bash as a language. I'm part of a very small crowd :)
- whateveracct 5y agoLarger than you'd think. Lots of people like to make a rich bashrc. Functions in a bashrc are amazing. And lots of people use Nix - and write a lot of bash.
- drran 5y agoCan you point to examples, please? `bash` is hard to write properly.
- whateveracct 5y agoIt is hard to write properly, but most use is hacky. It works for the intended purpose. ShellCheck does go a long way tho.
- dkdk8283 5y agoI’m a very big bash scripter - to the disdain of many younger colleagues. They prefer golang, typescript, node. I find it hard to relate. I write bash scripts to automate batch commands I find myself running as part of my job. I like the terminal and posix utilities. Very flexible and easy to read, to me.
- drran 5y agoCan I have a look at them?
- heavenlyblue 5y agoDoes your script parse arguments and provide good documentation with -h of what can be done with it but if needed?
- 5y ago
- shever73 5y agoI love bash scripting, but never knew about the ability to redefine existing commands. It made me think that it could be used maliciously, for example redefining cp so that sends a file to a remote server as well as copying it locally.
- barosl 5y agoIt absolutely can be used maliciously, but if an attacker can add an alias to the environment, they might also be able to manipulate PATH, making a malicious cp take precedence over the original cp. So the point is moot.
- avar 5y agoThat's not really a threat model to be concerned about, if someone can define bash aliases for you you're already running their arbitrary code, so them defining bash aliases for you should be the least of your concerns.
- rasguanabana 5y agoAlso, function body can be any compound command, so instead of braces {}, you can have parentheses (), which causes each function call to spawn a subshell. Very useful if your function needs isolated state or you change working directory and don’t want to affect global state. You can have exit command in such function, because it terminates the subshell only, not the whole script. 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.
- rgrau 5y agoPart of the mystery of the infamous shell fork bomb is that it picks a weird name like ':' for the function name. :(){ :|:& };: 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/ https://raimonster.com/scripting-field-guide/, in case anyone wants to give feedback (or PRs), it'd be much appreciated.
- yesenadam 5y agoGood stuff, thank you! Hope this helps a little. (I could send more corrections if you like as I read more.) 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
- rgrau 5y agothanks so much! I'll fix all those right away :+1:
- ufo 5y agoI'll take this chance to ask a fork bomb question I always had: on Linux, is there a way to stop a fork bomb once it gets going, other than turning off the power?
- 411111111111111 5y agoAs far as I know the only way to handle a fork bomb is to limit the allowed forks an instance is allowed to create. 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.
- hvdijk 5y ago> Bash has a handy POSIX mode which you can run your code under if you’re not sure if it’s portable or not. 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.
- pabs3 5y agoObligatory reference to shellcheck: https://www.shellcheck.net/ https://www.shellcheck.net/
- nickjj 5y agoIt's really nice to be able to use : to group up commands in a single file script that auto-converts functions to commands[0], such as ci:install-deps and ci:test. This has been a pattern I've been doing for a while now. [0]: https://nickjanetakis.com/blog/replacing-make-with-a-shell-script-for-running-your-projects-tasks https://nickjanetakis.com/blog/replacing-make-with-a-shell-s...
- jackewiehose 5y ago> The precise rules for function names are murky; mostly it seems like whatever Bash can parse unambiguously is allowed > 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.
- deleted 5y ago[deleted]
- chrismorgan 5y agoMy favourite shell scripting function definition technique: idempotent functions by redefining the function as a noop inside its body: 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.)
- rgrau 5y agowow, that's a great one!
- sqqqqrly 5y agoI love to use phony make recipes to package small bash scripts
- abarker 5y agoBash function names also have a different namespace than Bash variables, so you can define a function and a shell variable with the same name. I used that in a script which defines a function to be used like an alias to change to a specified directory, but where the name is also set as a shell variable that can be evaluated with $ to give the directory's pathname.