From 3f0660f117d46b12b066d0b1fca6cb4f1c6513b8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:10:18 +0000 Subject: [PATCH 2/3] Add robust shebang detection to .templates/01-config_yaml.sh Co-authored-by: alexbelgium <44178713+alexbelgium@users.noreply.github.com> --- .templates/01-config_yaml.sh | 142 ++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 1 deletion(-) 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 # ################## From 31221c5d9e8e43af8e7135feac0c4d34493147c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:16:18 +0000 Subject: [PATCH 3/3] Add robust shebang detection to 01-custom_script.sh; revert 01-config_yaml.sh Co-authored-by: alexbelgium <44178713+alexbelgium@users.noreply.github.com> --- .templates/01-config_yaml.sh | 142 +------------------------------ .templates/01-custom_script.sh | 149 +++++++++++++++++++++++++++++++-- 2 files changed, 143 insertions(+), 148 deletions(-) diff --git a/.templates/01-config_yaml.sh b/.templates/01-config_yaml.sh index 6cc6103ca..c2ccbd6de 100755 --- a/.templates/01-config_yaml.sh +++ b/.templates/01-config_yaml.sh @@ -1,146 +1,6 @@ -#!/bin/bash +#!/usr/bin/with-contenv bashio # 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 # ################## diff --git a/.templates/01-custom_script.sh b/.templates/01-custom_script.sh index f6477544a..a846cf7c3 100755 --- a/.templates/01-custom_script.sh +++ b/.templates/01-custom_script.sh @@ -1,7 +1,147 @@ -#!/usr/bin/with-contenv bashio +#!/bin/bash # shellcheck shell=bash set -e +########################################## +# 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 # ################## @@ -45,12 +185,7 @@ fi dos2unix "$CONFIGSOURCE" &> /dev/null || true chmod +x "$CONFIGSOURCE" -# Get current shebang, if not available use another -currentshebang="$(sed -n '1{s/^#![[:blank:]]*//p;q}' "$CONFIGSOURCE")" -if [ ! -f "${currentshebang%% *}" ]; then - for shebang in "/command/with-contenv bashio" "/usr/bin/env bashio" "/usr/bin/bashio" "/bin/bash" "/bin/sh"; do if [ -f "${shebang%% *}" ]; then break; fi; done - sed -i "s|$currentshebang|$shebang|g" "$CONFIGSOURCE" -fi +sed -i "1s|^.*|#!$shebang|" "$CONFIGSOURCE" # Check if there is actual commands while IFS= read -r line; do