diff --git a/.templates/01-config_yaml.sh b/.templates/01-config_yaml.sh index c2ccbd6de..6cc6103ca 100755 --- a/.templates/01-config_yaml.sh +++ b/.templates/01-config_yaml.sh @@ -1,6 +1,146 @@ -#!/usr/bin/with-contenv bashio +#!/bin/bash # shellcheck shell=bash +########################################## +# Pick an exec-capable directory # +########################################## + +pick_exec_dir() { + local d + for d in /dev/shm /run /var/run /mnt /root /; do + if [ -d "$d" ] && [ -w "$d" ]; then + local t="${d%/}/.exec_test_$$" + printf '#!/bin/sh\necho ok\n' >"$t" 2>/dev/null || { rm -f "$t" 2>/dev/null || true; continue; } + chmod 700 "$t" 2>/dev/null || { rm -f "$t" 2>/dev/null || true; continue; } + if "$t" >/dev/null 2>&1; then + rm -f "$t" 2>/dev/null || true + echo "$d" + return 0 + fi + rm -f "$t" 2>/dev/null || true + fi + done + return 1 +} + +EXEC_DIR="$(pick_exec_dir || true)" +if [ -z "${EXEC_DIR:-}" ]; then + echo "ERROR: Could not find an exec-capable writable directory." + exit 1 +fi + +###################### +# Select the shebang # +###################### + +candidate_shebangs=( + "/command/with-contenv bashio" + "/usr/bin/with-contenv bashio" + "/usr/bin/env bashio" + "/usr/bin/bashio" + "/usr/bin/bash" + "/bin/bash" + "/usr/bin/sh" + "/bin/sh" +) + +SHEBANG_ERRORS=() + +probe_script_content=' +set -e + +if ! command -v bashio::addon.version >/dev/null 2>&1; then + for f in \ + /usr/lib/bashio/bashio.sh \ + /usr/lib/bashio/lib.sh \ + /usr/src/bashio/bashio.sh \ + /usr/local/lib/bashio/bashio.sh + do + if [ -f "$f" ]; then + . "$f" + break + fi + done +fi + +bashio::addon.version +' + +validate_shebang() { + local candidate="$1" + local tmp out rc + local errfile msg + + # shellcheck disable=SC2206 + local cmd=( $candidate ) + local exe="${cmd[0]}" + + if [ ! -x "$exe" ]; then + SHEBANG_ERRORS+=(" - FAIL (not executable): #!$candidate") + return 1 + fi + + tmp="${EXEC_DIR%/}/shebang_test.$$.$RANDOM" + errfile="${EXEC_DIR%/}/shebang_probe_err.$$" + { + printf '#!%s\n' "$candidate" + printf '%s\n' "$probe_script_content" + } >"$tmp" + chmod 700 "$tmp" 2>/dev/null || true + + set +e + out="$("$tmp" 2>"$errfile")" + rc=$? + set -e + + rm -f "$tmp" 2>/dev/null || true + + if [ "$rc" -eq 0 ] && [ -n "${out:-}" ] && [ "$out" != "null" ]; then + rm -f "$errfile" 2>/dev/null || true + return 0 + fi + + msg=$' - FAIL: #!'"$candidate"$'\n'" rc=$rc, stdout='${out:-}'"$'\n' + if [ -s "$errfile" ]; then + msg+=$' stderr:\n' + msg+="$(sed -n '1,8p' "$errfile")"$'\n' + else + msg+=$' stderr: \n' + fi + SHEBANG_ERRORS+=("$msg") + rm -f "$errfile" 2>/dev/null || true + return 1 +} + +shebang="" +for candidate in "${candidate_shebangs[@]}"; do + if validate_shebang "$candidate"; then + shebang="$candidate" + break + fi +done + +if [ -z "$shebang" ]; then + echo "ERROR: No valid shebang found." >&2 + printf ' - %s\n' "${candidate_shebangs[@]}" >&2 + if [ "${#SHEBANG_ERRORS[@]}" -gt 0 ]; then + printf '%s\n' "${SHEBANG_ERRORS[@]}" >&2 + fi + exit 1 +fi + +sed -i "1s|^.*|#!$shebang|" "$0" + +if ! command -v bashio::addon.version >/dev/null 2>&1; then + for f in /usr/lib/bashio/bashio.sh /usr/lib/bashio/lib.sh /usr/src/bashio/bashio.sh /usr/local/lib/bashio/bashio.sh; do + if [ -f "$f" ]; then + # shellcheck disable=SC1090 + . "$f" + break + fi + done +fi + ################## # INITIALIZATION # ##################