pwned

I wrote the below BASH function today. It’s good because it performs super well compared to the alternative commands (which are commented out below above the new commands):

own() {

  echo "Taking ownership..."
  #chown -R jj5:jj5 .
  find . \! -user jj5 -or \! -group jj5 -execdir chown jj5:jj5  "{}" \;
  [ "$?" = 0 ] || { echo "Could not take ownership in '$PWD'."; exit 1; }

  echo "Fixing directory permissions..."
  #find . -type d -execdir chmod u+rwx "{}" \;
  find . -type d -and \( \! -perm /u=r -or \! -perm /u=w -or \! -perm /u=x \) -execdir chmod u+rwx "{}" \;
  [ "$?" = 0 ] || { echo "Could not fix directory permissions in '$PWD'."; exit 1; }

  echo "Fixing file permissions..."
  #find . -type f -execdir chmod u+rw "{}" \;
  find . -type f -and \( \! -perm /u=r -or \! -perm /u=w \) -execdir chmod u+rw "{}" \;
  [ "$?" = 0 ] || { echo "Could not fix file permissions in '$PWD'."; exit 1; }

}

The basic premise is don’t do work which doesn’t need to be done!

Removing colour code special characters with sed

I want to post-process the output of an ‘ls’ command with ‘sed’ so that I can remove the ‘./’ prefixes that I can’t avoid going into the ls output (this is a result of using ‘find’ safely).

The thing is, if I pipe ls output to sed, then the default –color=auto setting applies and ls detects that it’s not talking to a terminal so doesn’t output colour codes. But I want colour codes, usually, so I need to change the ls command to use –colour=always, which I’ve done. This means I can have colour and also have sed format the ls output.

The problem is then what happens if I want to pipe my output to ‘less’? Then the colour code commands appear as garbage in the output stream. So, usually I want colour codes, and sometimes I don’t.

I found this article, Remove color codes (special characters) with sed, which helped me come up with the following bash alias:

 alias noco='sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"'

So now that I have the ‘noco’ alias (short for “no colour”) I can pipe my output through that if I want the colour codes removed, which I can apply before piping output to less.

It’s a little bit annoying that I have to do things this way but I haven’t been able to think of a better way to make it all work and this all seems to get the job done.

Getting absolute path from relative path in Bash

I was writing a shell script and I wanted to change directory. But before I changed directory I wanted to get the absolute path to a file relative to the current directory so that I could access the file again later. I learned that you can do this in Bash with the readlink facility, passing in the -f command line switch, i.e.:

 $ readlink -f ./some/path

Bash wait

Today I learned about the ‘wait’ command. It waits for background processes to terminate before returning, so you can fire off a bunch of jobs to be run in parallel and then wait for all of them to complete before continuing, like in this take-ownership.sh script I wrote tonight:

#!/bin/bash
if [ -n "$1" ]; then
  pushd "$1" > /dev/null 2>&1
  if [ "$?" -ne "0" ]; then
    echo "Cannot change dir to '$1'.";
    exit 1;
  fi
fi
sudo chown -R jj5:jj5 . &
sudo find . -type d -exec chmod u+rwx {} \; &
sudo find . -type f -exec chmod u+rw {} \; &
if [ -n "$1" ]; then
  popd > /dev/null 2>&1
fi
wait
exit 0

Bash aliases for listing hidden files

I finally figured out the ls command to list hidden files, and decided to setup a ~/.bash_aliases file for the first time. My ~/.bash_aliases file is now:

alias l.='ls -d .[!.]*'
alias ll.='ll -d .[!.]*'

So I have an “l.” command which will list hidden files and directories, and an “ll.” command which will list the same information in detail.

Setting a default value if a bash variable is undefined

Say you want to take an optional command line argument to your script. That means that maybe $1 is set to a value, or maybe it’s not. You can read out the value and assign a default in the case that $1 is not set using the syntax:

  variable=${1:-default-value}

Which will set $variable to “default-value” if $1 is not set.