diff --git a/README.md b/README.md index e845566..f36efbf 100644 --- a/README.md +++ b/README.md @@ -1 +1,116 @@ -README +# Jan’s Shell Utilities + +I’m coming across having to write the same shell script bits occasionally, and I got tired of jumping backwards through my projects to find the latest version, so here is a repository. + +## Goals + +- Write once (here) and copypasta everywhere. +- sh compatible if possible + + +# Functions + +## `wait_for_url $url $duration $iterations` + +Wait for a particular URL to be available using `curl`. Wait `$duration` seconds between attempts, try `$iterations` times. Defaults to `1` seconds and `3` times. + +Signature: + +```shell +wait_for_url url [iterations duration] +``` + +Usage: + +```shell +source ./wait_for_url.sh + +# try 3 times, 1s apart +wait_for_url http://127.0.0.1:5984 + +# try 5 times, 1s apart +wait_for_url http://127.0.0.1:5984 5 3 + +# try 5 times, 3s apart +wait_for_url http://127.0.0.1:5984 5 3 +``` + +## `wait_for_pid_exit $pid $duration $iterations` + +Wait for a particular PID to exit. Wait `$duration` seconds between attempts, try `$iterations` times. Defaults to `1` seconds and `3` times. + +Signature: + +```shell +wait_for_pid_exit pid [iterations duration] +``` + +Usage: + +```shell +source ./wait_for_pid_exit.sh + +# try 3 times, 1s apart +wait_for_pid_exit 3618 + +# try 5 times, 1s apart +wait_for_pid_exit 3618 5 3 + +# try 5 times, 3s apart +wait_for_pid_exit 3618 5 3 +``` + +## `error_and_exit $message` + +Prints an error message and then exits with exit code `1`. + +Signature: + +```shell +error_and_exit [message] +``` + +Usage: + +```shell + +source ./lib + +# print message, then exit +error_and_exit "this did not work" +``` + +TODO: +- make exit code variable + - probably as `error_and_exit "msg" 17` + + +## `assert_arg $arg` + +Assert if a particular argument has been passed to a function. Combine with `&&` and `||` for error handling and setting of defaults for optional arguments. + +Signature: + +```shell +assert_arg arg +``` + +Usage: + +```shell +source ./lib.sh + + +# fail if arg is missing +function my_fun () { + assert_arg $1 && url=$1 || error_and_exit "error 'url' missing" + # now $url is available +} + +# set arg to default value if missing +function my_fun () { + assert_arg $1 && iterations=$1 || iterations=5 + # now $iterations is available +} + +``` diff --git a/lib.sh b/lib.sh new file mode 100644 index 0000000..d9b8c62 --- /dev/null +++ b/lib.sh @@ -0,0 +1,26 @@ + +function debug () { + if [ -n "$DEBUG" ]; then + echo "$1" + fi +} + +function debug_inline () { + if [ -n "$DEBUG" ]; then + printf "$1" + fi +} + +function error_and_exit () { + echo $1 || "error" + exit 1 +} + +function assert_arg () { + arg=$1 + + if [ -z "$arg" ]; then + return 1 + fi + return 0 +} diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..371e08a --- /dev/null +++ b/test.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +#source ./wait_for_url.sh +# +# echo test1 +# (wait_for_url) +# echo + +# echo test2 +# (wait_for_url http://localhost:8000 || echo "error reaching url") +# echo "test2 done" +# +# echo test3 +# (wait_for_url http://localhost:8000 4) +# echo +# +# echo test4 +# (wait_for_url http://localhost:8000 4 17) +# echo + + +source ./wait_for_pid_exit.sh + +echo test5 +(wait_for_pid_exit 45591 4 17) +echo "test5 done" \ No newline at end of file diff --git a/wait_for_pid_exit.sh b/wait_for_pid_exit.sh new file mode 100644 index 0000000..66f194c --- /dev/null +++ b/wait_for_pid_exit.sh @@ -0,0 +1,25 @@ + +source ./lib.sh + +function wait_for_pid_exit () { + assert_arg "$1" && pid="$1" || error_and_exit "pid not provided, exiting" + assert_arg "$2" && iterations="$2" || iterations=3 + assert_arg "$3" && duration="$3" || duration=1 + + debug "called wait_for_url(pid=pid, duration=$duration, iterations=$iterations)" + + waiting=0 + + debug_inline "waiting for $pid to exit " + until ( ! ps ax | grep $pid | grep -v grep > /dev/null); do + if [ $waiting -eq $iterations ]; then + let after=$duration*iterations + debug_inline "failed, $pid still running after $after seconds\n" + return 1 + fi + debug_inline . + let waiting=waiting+1 + sleep $duration + done + debug_inline " succeeded\n" +} diff --git a/wait_for_url.sh b/wait_for_url.sh new file mode 100644 index 0000000..8c2f95a --- /dev/null +++ b/wait_for_url.sh @@ -0,0 +1,26 @@ + +source ./lib.sh + +function wait_for_url () { + assert_arg "$1" && url="$1" || error_and_exit "url not provided, exiting" + assert_arg "$2" && iterations="$2" || iterations=3 + assert_arg "$3" && duration="$3" || duration=1 + + debug "called wait_for_url(url=$url, duration=$duration, iterations=$iterations)" + + waiting=0 + cmd="curl --output /dev/null --silent --insecure --head --fail --max-time 2 $url" + + debug_inline "waiting for $url " + until ($cmd); do + if [ $waiting -eq $iterations ]; then + let after=$duration*iterations + debug_inline "failed, $url can not be reached after $after seconds\n" + return 1 + fi + debug_inline . + let waiting=waiting+1 + sleep $duration + done + debug_inline " succeeded\n" +}