Skip to content

Instantly share code, notes, and snippets.

@iegik
Last active January 24, 2025 18:06
Show Gist options
  • Select an option

  • Save iegik/a2592cba598ce1a5f6ea to your computer and use it in GitHub Desktop.

Select an option

Save iegik/a2592cba598ce1a5f6ea to your computer and use it in GitHub Desktop.
Bash script template

Bourne Again SHell

Piping stdin

#!/bin/bash
if [[ -p /dev/stdin ]]
    then
    PIPE=$(cat -)
    echo "PIPE=$PIPE"
fi
echo "ARGS=$@"

Parse JSON

curl ... | jq -r '.data'
python ``` curl ... | python3 -c "import sys, json; print(json.load(sys.stdin)['data'])" ```

Math operations

echo $((5 - 3))

For in array

declare -a List=(en it de es pt fr et fi)
for lang in "${List[@]}"; do
    echo "$lang"
done

Loop for each line in file

while read LINE; do
  echo "$LINE"
done < ./file

Break loop on Ctrl+C

trap "exit" INT
while...

If

Operator Description
[ ! EXPRESSION ] The EXPRESSION is false.
[ -n STRING ] The length of STRING is greater than zero.
[ -z STRING ] The lengh of STRING is zero (ie it is empty).
[ STRING1 = STRING2 ] STRING1 is equal to STRING2
[ STRING1 != STRING2 ] STRING1 is not equal to STRING2
[ INTEGER1 -eq INTEGER2 ] INTEGER1 is numerically equal to INTEGER2
[ INTEGER1 -gt INTEGER2 ] INTEGER1 is numerically greater than INTEGER2
[ INTEGER1 -lt INTEGER2 ] INTEGER1 is numerically less than INTEGER2
[ INTEGER1 -le INTEGER2 ] INTEGER1 is numerically less than of equal to INTEGER2
[ -d FILE ] FILE exists and is a directory.
[ -e FILE ] FILE exists.
[ -r FILE ] FILE exists and the read permission is granted.
[ -s FILE ] FILE exists and it's size is greater than zero (ie. it is not empty).
[ -w FILE ] FILE exists and the write permission is granted.
[ -x FILE ] FILE exists and the execute permission is granted.
[[ "" =~ REGEX ]] REGEX check [[ "$foo" =~ ^bar$ ]]
if [ ... ] && [ ... ] AND
if [ ... ] || [ ... ] OR
// you always need to remember to double quote variables https://stackoverflow.com/questions/13617843/unary-operator-expected-error-in-bash-if-condition
if [ "$lang" = "en" ] ; then
    # ...
elif [ "$lang" = "fr" ] ; then
    # ...
else
    # ...
fi
for f in *.txt; do echo "mv $f ${f%%.txt}.md"; done

One line If

if [ $? -eq 0 ]; then echo 1; else echo 0; fi

Run command only after previous command is successful

command1 && command2

Run command only after previous command is unsuccessful

command1 || command2

File masks

ls file.(js|ts)
mv file.{js,ts} # mv file.js file.ts

Print on the same line

echo -ne  "Processing $i...\033[0K\r";

throw

throw() {
  echo -ne "\nERROR: $1\n"
  return 1
}

warn() {
  echo -ne "\n\033[1;33mWARN: $1\033[0m\n"
  return 0
}

Print links

printf '\e]8;;https://example.com\e\\example\e]8;;\e\\'
echo -e '\e]8;;https://example.com\e\\example\e]8;;\e\\'

Beep

echo '\a'

__dirname

__dirname=`dirname $0`
__filename=`basename $0`

Comments

# This is usual comment
echo a `# inline comment` \
  b # comment at the end of command

Loader

load() {
  ($1) & BACK_PID=$!
  spinner=(πŸ• πŸ•‘ πŸ•’ πŸ•“ πŸ•” πŸ•• πŸ•– πŸ•— πŸ•˜ πŸ•™ πŸ•š πŸ•›);
  while kill -0 $BACK_PID &> /dev/null ; do
    for c in "${spinner[@]}"; do echo -en "\033[2K\033[0;34m\r$c\033[0m $2"; sleep 0.1; done;
  done
}

x() { find . &>/dev/null; }

load x "In progress..."
progress() {
  ($1) & BACK_PID=$!
  c=".";
  while kill -0 $BACK_PID &> /dev/null ; do
    l=$(printf "%-$(</tmp/progress)s" "$c");
    echo -en "$(tput cuu1)\033[2K\r$2\n\033[2K\r\033[0;34m${l// /$c}\033[0m"; sleep 0.1;
  done
  echo -en "$(tput cuu1)\033[2K\r"
}

x() {
  echo 0 > /tmp/progress
  sleep 1;
  echo 50 > /tmp/progress
  sleep 1;
  echo 100 > /tmp/progress
}

progress x "In progress..."
echo -en "\033[2K\r\033[0;32mDone βœ“\033[0m\n"

Change to current directory

cd "${0%/*}"

Colors in Bash

echo -e "\033[1;31Text\033[0m"

Text
\033[   1;          31m      Text\033[  0m
^       ^ 0 Normal  ^ 8bit              ^ Clear
start     1 Bold      colors              color
color     2 Thin
mask      3 Italic
          4 Underline
Black 0;30 Dark Gray 1;30
Red 0;31 Light Red 1;31
Green 0;32 Light Green 1;32
Brown/Orange 0;33 Yellow 1;33
Blue 0;34 Light Blue 1;34
Purple 0;35 Light Purple 1;35
Cyan 0;36 Light Cyan 1;36
Light Gray 0;37 White 1;37
#!/bin/bash
USAGE=$(cat <<-EOM
Usage: ${0##*/} [OPTION]...
Lists all files recursively and shows the progress
EOM
)
# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
set -e
trap "exit" INT
throw() {
echo -ne "\033[0;31mERROR: $1\033[0m"
exit 1
}
warn() {
echo -ne "\033[1;33mWARN: $1\033[0m"
}
spinner() {
($1) & BACK_PID=$!
spinner=(πŸ• πŸ•‘ πŸ•’ πŸ•“ πŸ•” πŸ•• πŸ•– πŸ•— πŸ•˜ πŸ•™ πŸ•š πŸ•›);
while kill -0 $BACK_PID &> /dev/null ; do
for c in "${spinner[@]}"; do echo -en "\033[2K\033[0;34m\r$c\033[0m $2"; sleep 0.1; done;
done
}
debug=0
for i in "$@" ; do
case "$i" in
-t|--test ) shift ; debug=1 ;; # Switch to debug mode
-d|--directory ) shift ; path=$1 ; shift ;; # Pass name
-h ) echo "$USAGE" ; fgrep -h ')'' ' $0 | awk -F')'' | #'' ' '{printf "%-40s %s\n", $1, $3}' ; exit ; # Print this line
esac
done
if [ "$debug" -eq 1 ] ; then
warn "Debug mode is enabled"
echo "\$path: $path"
fi
if [ ! -d "$path" ] ; then
throw "Directory $path not found"
fi;
main() {
ls -RA "$path" &>/dev/null
}
spinner main "\033[3;30mProcessing \"$path\"...\033[0m"
echo -en "\033[2K\r\033[0;32mDone βœ“\033[0m\n"

Z SHell

zsh compinit: insecure directories

$ cd /usr/local/share/zsh
$ sudo chmod -R 755 ./site-functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment