Shell Snippets

Table of Contents

Change hostname howto

sudo sed -i "s/^127.0.0.1 localhost.*\$/127.0.0.1 localhost ${NEW_NAME}/" /etc/hosts
sudo bash -c "echo ${NEW_NAME} > /etc/hostname"
sudo hostname "${NEW_NAME}"

Force exit code 0 in spite of error howto

set -euo pipefail
<command> || true
echo 'Prints even if <command> fails'

Wait until a port available howto

# Wait until 3306 port available
while ! nc -z localhost 3306; do sleep 3; done

Get the source directory howto

DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

${BASH_SOURCE[0]} can also be used when the script is sourced, where $0 can't be used. Repalce BASH_SOURCE with $0 for zsh, taking account of the limitation.

Glob dotfiles howto

You can't just match dotfiles(whose names start with .) with the wildcard(*). There are some workarounds:

for item in .* *; do echo "$item"; done  # simplest

# for bash (shopt is bash specific)
shopt -s dotglob  # set dotglob
echo *
shopt -u dotglob  # unset dotglob

# for zsh (glob qualifier, GLOB_DOTS)
$ cp foo/*(D) .

Prevent partially downloaded scripts from executing howto

{
    # Your code here
}

Prompt a user for yes/no howto

read -p "Are you sure you want to continue? <y/N> " prompt
if [[ "$prompt" =~ [yY](es)* ]]; then
fi

Temporarily move to a different working directory via subshell howto

# do something in current dir
(cd /some/other/dir && other-command)
# continue in original dir

Trim a variable howto

trim() {
  local s="$1"
  # Remove leading whitespace characters
  s="${s#"${s%%[![:space:]]*}"}"
  # Remove trailing whitespace characters
  s="${s%"${s##*[![:space:]]}"}"
  echo -n "$s"
  #     └─ do not print the trailing newline character
}

Sort, uniquify, and other operations on file content howto

cat a b | sort | uniq > c        # c is a union b
cat a b | sort | uniq -d > c     # c is a intersect b
cat a b b | sort | uniq -u > c   # c is set difference a - b

grep . *     # overview for contents of current directory
head -100 *  # same as above, with only first 100 lines

# sum of all numbers in the third column
awk '{ x += $3 } END { print x }' myfile