-
-
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.