Bash Brackets Quick Reference

Ryan Palo on June 20, 2018

Cover image credit: Fonts.com Bash has lots of different kinds of brackets. Like, many much lots. It adds meaning to doubling up different bra... [Read Full]
markdown guide
 

You missed one of the really great BASHisms: <( COMMAND ). Basically, run command in a subshell, then return it's output through a file-descriptor. Meaning that you can do things like:

  • diff two streams
  • run a command within a shell to create an input-"file" for other commands that want input in the form of a file rather than a stream.

Another great one is VAR=($( COMMAND )) ...which takes the output from COMMAND and creates an array-variable from it.

Also useful is $( COMMAND )$? for when you care about how a command exited but not its output (e.g., you want to test to see if grep found a string in a file, [[ $( grep -q PATTERN FILE )$? ]].

 

These are great! When I get in front of a keyboard, I’ll add them to the list! Thanks for sharing. What are the most common file-expecting commands you use the sub shell redirect with?

 

AWS CLI for (particularly for CloudFormation) seems to not quite process STDIN for the --parameters flag as one might expect. Usually have to do something like what I put in my article when I'm doing stack-iterations as part of a quick test-change-test cycle (where "quick" is relative to things like RDS - there's frequently not enough time to wait for one launch to delete before moving on to the next launch).

Thanks again for the tips! I just wanted to let you know that I updated the article with your suggestions. 😀

 

A couple of things about HEREDOC bits:

  • HEREDOCs when used with a command are fed into stdin for a command. The way you've used it in your first example for assignment to a variable doesn't work, at least for me and my bash 4.4.19.
$ nice_message=<<MESSAGE
Hi there!  I really like the way you look
when you are teaching newbies things
with empathy and compassion!
You rock!
MESSAGE
$ echo $nice_message

$
$ cat <<MESSAGE
Hi there!  I really like the way you look
when you are teaching newbies things
with empathy and compassion!
You rock!
MESSAGE
Hi there!  I really like the way you look
when you are teaching newbies things
with empathy and compassion!
You rock!
$ 
  • If you put single quotes around the initial tag, the HEREDOC will be treated like a single-quoted string, leaving variable expressions uninterpolated.
$ cat <<EOF
$RANDOM
EOF
4578

$ cat <<'EOF'
$RANDOM
EOF
$RANDOM
  • You can also use triple less-than symbols without a tag to just feed in a single simple string, like so:
$ cat <<EOF
beep
EOF
beep

$ cat <<<beep
beep
$
 

Hm. I’ll take a look at that. Thanks! I was doing all of my local testing in Zsh, and forgot that there might be differences.

 

I updated the post with your help and extra info! Thanks again!

 

This is a really great overview. Probably the clearest thing I've ever read about substitutions and their ilk :)

One thing I might add to it would be just to flag which bits are POSIX. Like where you have the single- vs. double-square-brackets rule of thumb, you say that if you need to use test or [ you'll know it - well the main reason you'd know it is if you were wanting to write a script which might be portable, i.e. work in a foreign shell.

 

Thanks! I’ll put something in there about that. I tried to avoid it, because I found during my research that articles that constantly focused on POSIX really distracted from the rest of the info. But you are right that it’s probably good to at least mention that it is a thing.

Thanks for the feedback!

 

Small fix for -
echo ${url%%/*}

It actually prints -
https:

 

Ah! You're totally right. Let me get that fixed. Thanks!

 

This is great! I use bash a ton but wasn't aware of several of these. Really useful.

 

Thanks! Glad it was able to help you out!

 

Love this post. Bash has remained something I've been content to stumble around with instead of learning, but this got me intrigued.

 

Heh... There's so much I can do with BASH that, when under a time-crunch, it's hard for me to justify figuring out "how do I accomplish 'X' in <INSERT_LANGUAGE_OR_DSL>" ...when I can just bang it out in BASH in like two seconds

 

Yeah, I logically know all of this but have still maintained vast ignorance.

 

Basically until I wrote this, I just guessed and then tried another set of brackets when one didn’t work. I do that with a lot of stuff in Bash, so I’m going back to fill in all the gaps.

 

There is also triple < here doc that provides a string as stdin input, e.g.
cat <<<"this string"

 

Cool! Does this give you any benefits over “echo some string | cat”? I guess it saves cat from being run in a sub shell, maybe?

 
 
 

I once renegotiated my salary when the CTO asked "But how did you passed standard input to the application?". Got a 30%. lolz ;..;

 

Great summary.

I've written a ton of bash.

My rule for writing bash is to write as little bash as possible.

Anything with any sort of even mildly complex logic, use a modern scripting language - Ruby (my preference) or Python.

I've also written github.com/thewoolleyman/process_h... which makes dealing with subprocesses much nicer in Ruby.

 

Well, after Powershell all this seems not even ugly, but as a product of some extraterrestrial mind.
I really have no idea why would anyone use it in 2018 voluntarily.

 

I know both bash and powershell and i can tell you're just trolling: powershell certainly is the alien language. As for who would use bash in 2018 voluntarily, i guess most developers do, contrary to powershell.

 

Nice try.

BTW, I wasn't trolling at all, so you don't need to 'overtroll' anybody.

code of conduct - report abuse