-
-
Save mplewis/62fb4868f92db166744f9a94ee12610d to your computer and use it in GitHub Desktop.
#!/bin/bash | |
# http://redsymbol.net/articles/unofficial-bash-strict-mode/ | |
set -euo pipefail | |
IFS=$'\n\t' | |
set -x | |
# http://blog.pkh.me/p/21-high-quality-gif-with-ffmpeg.html | |
# Default settings work great for screencasts. For video from an actual camera, set MOTION=1. | |
MOTION=${MOTION:-} | |
if [ ! -z "${MOTION}" ]; then | |
DITHER=sierra2_4a | |
STATS_MODE=diff | |
NO_DIFF_RECT=1 | |
fi | |
FPS=${FPS:-15} | |
WIDTH=${WIDTH:--1} | |
HEIGHT=${HEIGHT:--1} | |
DITHER=${DITHER:-none} | |
STATS_MODE=${STATS_MODE:-full} | |
START_TIME=${START_TIME:-0} | |
DURATION=${DURATION:-0} | |
NO_DIFF_RECT=${NO_DIFF_RECT:-} | |
AND_DIFF_MODE=${AND_DIFF_MODE:-:diff_mode=rectangle} | |
if [ ! -z "${NO_DIFF_RECT}" ]; then | |
AND_DIFF_MODE='' | |
fi | |
filters="fps=$FPS,scale=$WIDTH:$HEIGHT:flags=lanczos" | |
palette="/tmp/palette.png" | |
ffmpeg -ss "$START_TIME" -t "$DURATION" -i "$1" -vf "$filters,palettegen=stats_mode=$STATS_MODE" -y $palette | |
ffmpeg -ss "$START_TIME" -t "$DURATION" -i "$1" -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse=dither=$DITHER$AND_DIFF_MODE" -y "$2" |
Always quote when testing with -z
. Otherwise anything in IFS will expand to separate words:
✘-127 ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4]
14:46 $ IFS=$'\t\n'; ARR=($'element\t1' $'element\n2' $'element3\t'); printf -- '---%s---\n' "${ARR[@]}"; for e in "${ARR[@]}"; do if [ -z $e ]; then echo 'Empty!'; else echo 'Not!'; fi; done
---element 1---
---element
2---
---element3 ---
-bash: [: element: binary operator expected
Not!
-bash: [: element: binary operator expected
Not!
Not!
✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4]
14:46 $ IFS=$'\t\n'; ARR=($'element\t1' $'element\n2' $'element3\t'); printf -- '---%s---\n' "${ARR[@]}"; for e in "${ARR[@]}"; do if [ -z "$e" ]; then echo 'Empty!'; else echo 'Not!'; fi; done
---element 1---
---element
2---
---element3 ---
Not!
Not!
Not!
Of course, my second advice is to use [[
instead, then you don't need to worry about it:
✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4]
14:48 $ IFS=$'\t\n'; ARR=($'element\t1' $'element\n2' $'element3\t'); printf -- '---%s---\n' "${ARR[@]}"; for e in "${ARR[@]}"; do if [[ -z $e ]]; then echo 'Empty!'; else echo 'Not!'; fi; done
---element 1---
---element
2---
---element3 ---
Not!
Not!
Not!
[
has a bunch of backward-compatibility cruft, it's a bash built-in that emulates /bin/[
, which is just an alias for /bin/test
. [[
is a bash keyword that applies more friendly parsing rules within [[
/]]
.
On lines 28-29, what happens if $pallette
has space in it? Always quote variable expansion unless you know for sure you don't need to. In this case, you do know for sure since it's defined 1 line above, so nevermind.
Except don't! Quote your ENV=${ENV:-default}
stuff.
Oh yeah, re: the ARR
stuff, check this out:
✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4]
14:43 $ IFS=$'\t\n'; ARR=($'element\t1' $'element\n'2); printf -- '---%q---\n' "${ARR[@]}"
---$'element\t1'---
---$'element\n2'---
%q
rules!
e: Not appropriate for your use-case right now, but I really like it for displaying "File not found: $(printf '%q' "$FILE")" so people can actually see what the value passed was.
✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4]
14:58 $ printf 'File not found: %s\n' "File with a space at the end "
File not found: File with a space at the end
✔ ~/workspace/zenpayroll [davec-employment-verification L|●1✚ 4]
14:58 $ printf 'File not found: %q\n' "File with a space at the end "
File not found: File\ with\ a\ space\ at\ the\ end\
Line 4: There's no need to change IFS. The link that recommends this misses a more effective fix that doesn't either change behavior of downstream scripts (
export IFS
) or require applying it in every new context (including stuff like "$(command)"):Just quote it. This also misses the entire point of [@] element access:
I didn't read that page super closely, but I think the author has an inflated sense of their own competence and should understand bash better before trying to create even an unofficial standard.