Nithin Bekal Posts About Notes



cat hello.txt
echo 'Hello!'
# Sends to stdout

echo 'Bye!' > bye.txt # write to file
echo 'Bye again' >> bye.txt # Append

cat non-existent-file 2> errors.txt # redirect stderr
cat existing-file 2> errors.txt # errors.txt is empty
# prints file contents

# Combined output - both stdout and stderr
cat hello.txt non-existent.txt &> combined.txt

# Throw away all output
cat hello.txt non-existent.txt &> /dev/null

# pipes and stdin
sort hello.txt | grep Hello | sed 's/Hello/Hey/'


#! /bin/sh

set -e
set -o pipefail

echo 'Hello'
chmod +x

set -e - stop and raise immediately on any error. Always exit early.

set -o pipefail - without this, a command is considered to be failing if any of the commands in a pipeline fail.

Eg. grep foo missing-file.txt | sed 's/hello/hey'

The grep fails, and writes empty string to stdout, so sed won’t fail. This command is considered ok by default, but pipefail exits as soon as grep fails.

$? - most reent exit code - 0 indicates success

foo && bar - second thing runs only if first succeeds.

An example script:

$ ls services
rails.service postgres.service some-other-file.txt

$ cat services/rails.service
name rails
port 3000

$ cat services/postgres.service
name postgres
port 5432
#! /bin/bash

set -e
set -o pipefail

# Exit early if no arguments given
# Usage: ./ services-dir
if [ $# -eq 0 ]; then
  echo "Error: Provide the name of the services directory."
  exit 64 # Recommended code for wrong number of args

print_services() {
  # -q option -> quiet
  if grep -q port "$1" && grep -q name "$1"; do
    name=$(grep name "$1" | sed 's/name //')

    if [ $port -lt 5000 ]; then
      echo "Greater than 5000"

    echo "$1: $name $port"
    echo "$1 Missing name or port"

for file in $1/*.service; do
  print_service "$file"

Other zsh tips

Inserting last argument in zsh:

  • Use !$ to insert last command’s arg or ESC-.
  • !* inserts all args