Today I learned that each sequence in a bash pipeline executes in a separate subshell…this means variables cannot be passed along the pipeline, as each new subprocess invokes a brand new environment.

For some workarounds checkout http://mywiki.wooledge.org/BashFAQ/024

Tags: bash shell unix

It is 2013, we (still) don't have flying cars, or hoverboards, AND as developers, we still use terminals to interact with our operating system. So every so often I like to browse through commandlinefu.com and try and pick up any little tidbits which improve my command line efficiency.

Here's a small selection I have picked up recently that I didn't know.

sudo !! 

Run the previous command as sudo. This is great when you realise you needed to run something as root.

ctrl-x e

Open up $EDITOR to enter in a long command. In my setup it fires up vim. This is great for some of the long rails commands you need to create controllers or models.

cat /etc/passwd | column -s':' -t 

Column, columnates input, the -t argument will format standard input into a table and -s lets you specify an arbitrary field delimiter. For unformatted input this is very handy.

These next few are specific to zsh, and while I do love bash, since switching to zsh I haven't really looked back. It's things like this that when you work with a terminal every single day, you can't give up.

[email protected] ~ $ d                                 
  0    ~
  [email protected] ~ $ cd /etc
  [email protected] /etc $ d
  0    /etc
  1    ~
  [email protected] /etc $ 1
  [email protected] ~ $  

The 'd' command lists the directory stack, and then entering an integer will switch you directly to the directory index in the stack. It is a killer app.

Moving directories also is very pleasant in zsh. Use '..' to move up a directory, and simply type the name of the directory in, to move into a directory.

[email protected] ~ $ ..       
  [email protected] /Users $ aaron
  [email protected] ~ $ 

This last one is a trick I've know for a few years, I don't know how much time this has saved me exactly, but I use it every single day.

In vim, if you're editing a file that requires root (or any other user) permissions, you can write the file by doing

:w !sudo tee %

I use it so much that I've set up a leader key binding in my .vimrc

nnoremap <leader>sr :w !sudo tee %<CR>

There's nothing more annoying than making lengthy changes to a config file, go to write it and getting permission denied...

I make all my configs available online at github, if you're interested in seeing how I setup my environment.


A quick bit of shell-fu.

To take a column from a MySQL database and quickly output it ready formatted as a Javascript array literal (without any specific escaping) do:

echo 'SELECT column FROM table WHERE some_column = "somevalue"' | mysql -uuser -ppass --silent yourdb | awk -v q="'" '{ print q $0 q }' | paste -s -d ',' | sed 's/(.*)/[\1];/'

The first part of the command is self explanatory, you pipe in a query to mysql, and ask it to give you raw unadorned output. It will return each row for column 'column' from table 'table' as a line of output.

You pipe it to awk and ask it to wrap the values in single quotes. Due to shell escaping with single quotes, you set the q variable to a single quote. Paste then joins all the output lines together separated by commas.

Finally I use sed to wrap the resulting output in Javascript array literal '[' and ']' symbols. Awk or any other tool to concatenation approach would do just fine here too.


It can be confusing which file to put certain shell / environment setup information in.

Generally speaking (i.e. not with Mac OSX's Terminal.app) .bash_profile gets sourced only on login. Specifically this means only when you enter your username and password from the console. The .bashrc file is sourced when starting an interactive session, that is, whenever you open up a terminal.

There is some confusion here, when you open up a login shell, such as if you use the su - command or run an explicit login shell sometimes provided by a desktop environment. In these cases the rule applies, a login shell means .bash_profile is sourced first, then .bashrc.

I tend to put environment setup in bash_profile, things like paths and any specific one-time configuration settings that aren't likely to change very much. But it's quite reasonable to just put a source .bashrc in your .bash_profile and then put everything in .bashrc.

Tags: bash