diff --git a/profile.d/compress.sh b/profile.d/compress.sh index 23fef55..ee2ee69 100644 --- a/profile.d/compress.sh +++ b/profile.d/compress.sh @@ -44,36 +44,42 @@ # -n, --no-dir Never create a host directory utaz() { + # shellcheck disable=SC2329 _ununzip() { unzip -o "$1" -d "$2" >/dev/null 2>&1 } + # shellcheck disable=SC2329 _untar() { tar -xf "$1" -C "$2" } + # shellcheck disable=SC2329 _ungzip() { tar -xzf "$1" -C "$2" } - + # shellcheck disable=SC2329 _unbzip2() { tar -xjf "$1" -C "$2" } + # shellcheck disable=SC2329 _unxz() { tar -xJf "$1" -C "$2" } + # shellcheck disable=SC2329 _unlzop() { lzop -d "$1" -o "$2/$(basename "${1%.*}")" } + # shellcheck disable=SC2329 _unlzip() { if command -v plzip >/dev/null 2>&1; then @@ -83,16 +89,19 @@ utaz() fi } + # shellcheck disable=SC2329 _ununrar() { unrar x -o+ "$1" "$2/" >/dev/null 2>&1 } + # shellcheck disable=SC2329 _ununarj() { unarj e "$1" "$2/" >/dev/null 2>&1 } + # shellcheck disable=SC2329 _unlha() { # lha typically extracts into the current directory @@ -100,40 +109,47 @@ utaz() (cd "$2" && lha -x "../$1") >/dev/null 2>&1 } + # shellcheck disable=SC2329 _ununace() { unace x "$1" "$2/" >/dev/null 2>&1 } + # shellcheck disable=SC2329 _un7z() { 7z x "$1" -o"$2/" >/dev/null 2>&1 } + # shellcheck disable=SC2329 _unzstd() { # Zstd decompresses files directly, often requiring tar for archives tar --zstd -xf "$1" -C "$2" } + # shellcheck disable=SC2329 _uncpio() { # CPIO requires careful directory handling (cd "$2" && cpio -id < "../$1") >/dev/null 2>&1 } + # shellcheck disable=SC2329 _uncabextract() { # Requires 'cabextract' package cabextract "$1" -d "$2/" >/dev/null 2>&1 } + # shellcheck disable=SC2329 _undeb() { # Extracts data content from a Debian package dpkg-deb -x "$1" "$2/" >/dev/null 2>&1 } + # shellcheck disable=SC2329 _unrpm() { # Extracts CPIO-based payload from an RPM package @@ -141,8 +157,9 @@ utaz() rpm2cpio "$1" | (cd "$2/" && cpio -idmv) >/dev/null 2>&1 } - local PARSED=$(getopt -o hdcn --long help,delete,create-dir,no-dir -n 'utaz' -- "$@") - + local PARSED + PARSED=$(getopt -o hdcn --long help,delete,create-dir,no-dir -n 'utaz' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [ $? -ne 0 ]; then disp E "Invalid options, use \"utaz --help\" to display usage." return 1 @@ -314,10 +331,10 @@ utaz() fi disp I "Processing archive ${f} with ${extractor}..." - mkdir -p "${dir}" - [[ $? -gt 0 ]] && + if ! mkdir -p "${dir}"; then disp E "The filesystem can't create directories, exit!" && return 1 + fi ${extractor} "${f}" "${dir}" case $? in @@ -390,6 +407,7 @@ export -f utaz # -1, .., -9 Compression level to use [1=fast/biggest, 9=slow/smallest] taz() { + # shellcheck disable=SC2329 _doxz() { command -v xz >/dev/null 2>&1 || { @@ -397,17 +415,19 @@ taz() return 127 } - [[ $4 ]] && local verb='-v' + local verb=() + [[ $4 ]] && verb=('-v') # Display a warning for this format disp W "xz format is not suited for long term archiving." disp I "See https://www.nongnu.org/lzip/xz_inadequate.html for details." # Compresse to xz (lzma2) - Deprecated - xz $verb --compress --keep -$3 -T $2 $1 + xz "${verb[@]}" --compress --keep "-$3" -T "$2" "$1" return $? } + # shellcheck disable=SC2329 _dolz() { local procopt="--threads $2" @@ -425,13 +445,16 @@ taz() disp W "Consider installing plzip to obtain multithreading abilities." } - [[ $4 ]] && local verb="-vv" + local opt=() + [[ $4 ]] && opt=('-vv') + opt+=("$procopt") # Compresse au format lzip (lzma) - $command $verb $procopt --keep -$3 $1 + $command "${opt[@]}" --keep "-$3" "$1" return $? } + # shellcheck disable=SC2329 _dogz() { local procopt="--processes $2" @@ -449,13 +472,16 @@ taz() disp W "Consider installing pigz to obtain multithreading abilities." } - [[ $4 ]] && local verb="--verbose" + local opt=() + [[ $4 ]] && opt=('--verbose') + opt+=("$procopt") # Compresse au format bz2 - $command $verb $procopt --keep -$3 $1 + $command "${opt[@]}" --keep "-$3" "$1" return $? } + # shellcheck disable=SC2329 _dobz2() { local procopt="-p$2" @@ -473,13 +499,16 @@ taz() disp W "Consider installing pbzip2 to obtain multithreading abilities." } - [[ $4 ]] && local verb="-v" + local opt=() + [[ $4 ]] && opt=('-v') + opt+=("$procopt") # Compresse au format bz2 - $command $verb --compress $procopt --keep -$3 $1 + $command "${opt[@]}" --compress --keep "-$3" "$1" return $? } + # shellcheck disable=SC2329 _dolzo() { command -v lzop >/dev/null 2>&1 || { @@ -487,16 +516,18 @@ taz() return 127 } - [[ $4 ]] && local verb='-v' + local verb=() + [[ $4 ]] && verb=('-v') [[ $2 -gt 1 ]] && disp W "lzop doesn't support multithreading, falling back to 1 thread." # Compresse au format lzo - lzop --keep -$3 $1 + lzop "${verb[@]}" --keep "-$3" "$1" return $? } local PARSED PARSED=$(getopt -o hdf:p:vq123456789 --long help,delete,format:,parallel:,verbose,quiet --name "taz" -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [ $? -ne 0 ]; then disp E "Invalid options, use \"taz --help\" to display usage." return 1 @@ -587,8 +618,7 @@ taz() if [[ -d "$item" ]]; then disp I "\t Creating $item.tar... " - tar -cf "$item.tar" "$item" - if [[ ! $? -eq 0 ]]; then + if ! tar -cf "$item.tar" "$item"; then disp E "tar file creation failed, skipping to next item." continue fi @@ -602,8 +632,9 @@ taz() # Skip compression part if tar is asked if [[ $compform != "tar" ]]; then disp I "\t Compressing archive..." - _do$compform "$fname" "$nproc" "$complevel" "$verbose" - [[ ! $? -eq 0 ]] && case $? in + local exec_code=0 + "_do$compform" "$fname" "$nproc" "$complevel" "$verbose" || exec_code=$? + [[ ! $exec_code -eq 0 ]] && case $exec_code in 127) disp E "Compression program unavailable, aborting." return 127 diff --git a/profile.d/debug.sh b/profile.d/debug.sh index a55a68f..5b3e119 100644 --- a/profile.d/debug.sh +++ b/profile.d/debug.sh @@ -70,6 +70,7 @@ settrace() local PARSED PARSED=$(getopt -oh --long help,on,off,status,force -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"settrace --help\" to display usage." return 1 diff --git a/profile.d/filefct.sh b/profile.d/filefct.sh index 6d571c0..8175cbd 100644 --- a/profile.d/filefct.sh +++ b/profile.d/filefct.sh @@ -41,8 +41,8 @@ expandlist() { local separator="${EXPANDLIST_DEFAULT_SEPARATOR:- }" local PARSED - PARSED=$(getopt -o hs:n --long help,separator:,newline -n 'expandlist' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"expandlist --help\" to display usage." return 1 @@ -87,6 +87,7 @@ expandlist() # True glob expansion when wildcards are present. if [[ "$item" == *'*'* || "$item" == *'?'* || "$item" == *'['* ]]; then + # shellcheck disable=SC2206 # We actually want the word splitting expanded=( $item ) else expanded=( "$item" ) @@ -127,7 +128,7 @@ clean() # Define short and long options local PARSED PARSED=$(getopt -o hrsf --long help,recurs,shell,force -n 'clean' -- "$@") - + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"clean --help\" to display usage." return 1 @@ -215,10 +216,14 @@ mcd() disp E "Missing parameter. Use \"mcd --help\" to display usage." return 1 fi - mkdir -pv "$1" && cd "$1" || { - printf "Failed create and/or change directory.\n" + if ! mkdir -pv "$1"; then + disp E "Failed to create directory \"$1\"." return 1 - } + fi + if ! cd "$1"; then + disp E "Failed to change to directory \"$1\"." + return 1 + fi } export -f mcd # ------------------------------------------------------------------------------ @@ -241,6 +246,7 @@ rmspc() local PARSED PARSED=$(getopt -o hr:c::vs --long help,recursive,subst-char::,verbose,shell -n 'rmspc' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"rmspc --help\" to display usage." return 1 @@ -359,7 +365,7 @@ file_stats() # Short: H, d, m, M, c, t, a, x:, X: # Long: human, details, average, median, count, total, all, ext:, ext-list:, min:, max:, help PARSED=$(getopt -o HdmMctax:X:h --long human,details,average,median,count,total,all,ext:,ext-list:,min:,max:,help -n 'file_stats' -- "$@") - + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"file_stats --help\" to display usage." return 1 @@ -578,6 +584,7 @@ findbig() local PARSED PARSED=$(getopt -o hdl:x --long help,details,limit:,one-fs -n 'findbig' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"findbig --help\" to display usage." return 1 @@ -660,6 +667,7 @@ findzero() local PARSED # o: options, long: long equivalents PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'findzero' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"findzero --help\" to display usage." return 1 @@ -733,6 +741,7 @@ finddead() local PARSED PARSED=$(getopt -o hdx --long help,details,one-fs,delete -n 'finddead' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"finddead --help\" to display usage." return 1 diff --git a/profile.d/fun.sh b/profile.d/fun.sh index e547ff8..7def811 100644 --- a/profile.d/fun.sh +++ b/profile.d/fun.sh @@ -48,6 +48,7 @@ busy() # Short: h, p:, d: # Long: help, pattern:, delay: PARSED=$(getopt -o hp:d: --long help,pattern:,delay: -n 'busy' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"busy --help\" to display usage." return 1 @@ -89,7 +90,8 @@ busy() done # Convert milliseconds to seconds for 'sleep' - local delay_s=$(awk "BEGIN{ + local delay_s + delay_s=$(awk "BEGIN{ printf \"%.3f\", $delay_ms / 1000 }") # Monitor /dev/urandom diff --git a/profile.d/help.sh b/profile.d/help.sh index 5f9854c..0f93db6 100644 --- a/profile.d/help.sh +++ b/profile.d/help.sh @@ -39,6 +39,8 @@ # Usage: help help() { + # shellcheck disable=SC2154 # color code in disp.sh + # shellcheck disable=SC2059 # printf format is a color variable printf "${BIWhite}Welcome to your profile! Here is a list of available commands:${DEFAULTCOL}\n\n" printf "busy\t\tMonitor /dev/urandom for a hex pattern — look busy\n" printf "check_updates\tCheck for new versions of profile\n" diff --git a/profile.d/info.sh b/profile.d/info.sh index c610475..5e0733d 100644 --- a/profile.d/info.sh +++ b/profile.d/info.sh @@ -42,6 +42,7 @@ ver() local PARSED PARSED=$(getopt -o h --long help -n 'ver' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"ver --help\" to display usage." return 1 @@ -82,6 +83,7 @@ meteo() local PARSED PARSED=$(getopt -o h --long help -n 'meteo' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"meteo --help\" to display usage." return 1 @@ -133,6 +135,7 @@ showinfo() local PARSED PARSED=$(getopt -o h --long help -n 'showinfo' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"showinfo --help\" to display usage." return 1 diff --git a/profile.d/lang.sh b/profile.d/lang.sh index 8d7014c..4319854 100644 --- a/profile.d/lang.sh +++ b/profile.d/lang.sh @@ -51,6 +51,7 @@ setlocale() { local PARSED PARSED=$(getopt -o h --long help -n 'setlocale' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"setlocale --help\" to display usage." return 1 diff --git a/profile.d/net.sh b/profile.d/net.sh index 5efb5db..166949c 100644 --- a/profile.d/net.sh +++ b/profile.d/net.sh @@ -70,9 +70,32 @@ dwl() # Honour preferred tool from configuration; fall back to auto-detection. local preferred="${DWL_PREFERRED_TOOL:-}" - _try_curl() { [ -z "$output" ] && curl -sL "$url" || curl -sL -o "$output" "$url"; } - _try_wget() { [ -z "$output" ] && wget -qO- "$url" || wget -q -O "$output" "$url"; } - _try_fetch() { [ -z "$output" ] && fetch -o - "$url" || fetch -o "$output" "$url"; } + _try_curl() + { + if [[ -z "$output" ]]; then + curl -sL "$url" + else + curl -sL -o "$output" "$url" + fi + } + + _try_wget() + { + if [[ -z "$output" ]]; then + wget -qO- "$url" + else + wget -q -O "$output" "$url" + fi + } + + _try_fetch() + { + if [[ -z "$output" ]]; then + fetch -o - "$url" + else + fetch -o "$output" "$url" + fi + } if [[ -n "$preferred" ]]; then command -v "$preferred" >/dev/null 2>&1 || { diff --git a/profile.d/packages.sh b/profile.d/packages.sh index 811354e..15d7d37 100644 --- a/profile.d/packages.sh +++ b/profile.d/packages.sh @@ -43,6 +43,7 @@ pkgs() local PARSED PARSED=$(getopt -o hi --long help,ignore-case -n 'pkgs' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"pkgs --help\" to display usage." return 1 @@ -87,10 +88,10 @@ pkgs() command -v dpkg >/dev/null 2>&1 && local cmd="dpkg -l" command -v rpm >/dev/null 2>&1 && local cmd="rpm -qa" if [[ -z $cmd ]]; then - disp E "No usable package manager seems unavialable." + disp E "No usable package manager seems avialable." return 2 fi - $cmd | grep $grep_opt $pkg + $cmd | grep "$grep_opt" "$pkg" } export -f pkgs # ------------------------------------------------------------------------------ diff --git a/profile.d/processes.sh b/profile.d/processes.sh index 4567e2e..a94e479 100644 --- a/profile.d/processes.sh +++ b/profile.d/processes.sh @@ -121,6 +121,7 @@ ppn() # -e: select all processes # -o: specify custom output columns (PID and Command name) # grep -w: ensures exact word matching so 'bash' doesn't match 'dbash' + # shellcheck disable=SC2009 # pgrep do not offer the -w switch ps -eo pid,comm | grep -w "$1" } export -f ppn @@ -200,8 +201,7 @@ ku() disp E "Usage: ku " return 1 fi - local users="$@" - for u in $users; do + for u in "$@"; do if ! id "$u" >/dev/null 2>&1; then disp E "User '$u' does not exist." return 1 @@ -238,7 +238,8 @@ kt() return 1 fi - local children_pids=$(pgrep -P "$parent_pid") + local children_pids + children_pids=$(pgrep -P "$parent_pid") for pid in $children_pids; do kt "$pid" "$@" || break diff --git a/profile.d/prompt.sh b/profile.d/prompt.sh index 14c00e3..f168fcf 100644 --- a/profile.d/prompt.sh +++ b/profile.d/prompt.sh @@ -252,7 +252,7 @@ function timer_start # into a human-readable string with appropriate units (us, ms, s, m, h function timer_stop { - local delta_us=$((($(timer_now) - $timer_start) / 1000)) + local delta_us=$((($(timer_now) - timer_start) / 1000)) local us=$((delta_us % 1000)) local ms=$(((delta_us / 1000) % 1000)) local s=$(((delta_us / 1000000) % 60)) diff --git a/profile.d/pwd.sh b/profile.d/pwd.sh index 02e4071..e4e55ea 100644 --- a/profile.d/pwd.sh +++ b/profile.d/pwd.sh @@ -65,6 +65,7 @@ genpwd() PARSED=$(getopt -o hsnule:L:o: --long \ help,nosymbols,nonumbers,noup,nolow,extracars:,length:,occurences:,occurrences: \ -n 'genpwd' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then return 1; fi eval set -- "$PARSED" diff --git a/profile.d/ssh.sh b/profile.d/ssh.sh index 187b8ec..7bcf65e 100644 --- a/profile.d/ssh.sh +++ b/profile.d/ssh.sh @@ -44,6 +44,7 @@ rmhost() local -a known_hosts_files=() PARSED=$(getopt -o ha --long help,all-users -n 'rmhost' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then return 1; fi eval set -- "$PARSED" @@ -194,6 +195,7 @@ ssr() ssh_default_opts=(-Y) fi + # shellcheck disable=SC2029 ssh "${ssh_default_opts[@]}" root@"$srv" "$@" } export -f ssr diff --git a/profile.d/updates.sh b/profile.d/updates.sh index 5ad112c..37d9fc6 100644 --- a/profile.d/updates.sh +++ b/profile.d/updates.sh @@ -54,6 +54,7 @@ check_updates() local vfile="" lastver="" PARSED=$(getopt -o hq --long help,quiet -n 'check_updates' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"check_updates --help\" to display usage." return 2 @@ -128,6 +129,7 @@ profile_upgrade() local tmpdir="" archive="" extracted_root="" PARSED=$(getopt -o hf:t:nFb:g --long help,file:,tmpdir:,dry-run,force,branch:,switch-to-git -n 'profile_upgrade' -- "$@") + # shellcheck disable=SC2181 # getopt return code is checked immediately after if [[ $? -ne 0 ]]; then disp E "Invalid options, use \"profile_upgrade --help\" to display usage." return 2 @@ -215,8 +217,8 @@ profile_upgrade() } if (( dry_run )); then disp I "[dry-run] rm -rf \"$MYPATH\"/.git" - disp I "[dry-run] git clone "$BASE_URL" \"$MYPATH\"" - [[ -n "$branch" ]] && disp I "[dry-run] git -C \"$MYPATH\" checkout "$branch"" + disp I "[dry-run] git clone $BASE_URL \"$MYPATH\"" + [[ -n "$branch" ]] && disp I "[dry-run] git -C \"$MYPATH\" checkout $branch" return 0 fi diff --git a/profile.sh b/profile.sh index 84b3399..6834a52 100644 --- a/profile.sh +++ b/profile.sh @@ -45,7 +45,7 @@ fi if ((BASH_VERSINFO[0] < 4)) || [[ ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 3 ]]; then echo "[ Error ] This profile requires Bash 4.3 or higher." echo "Current version: $BASH_VERSION" - return 1 2>/dev/null || exit 1 + (return 0 2>/dev/null) && return 1 || exit 1 fi # ------------------------------------------------------------------------------ @@ -66,17 +66,17 @@ pathremove() export "$pathvar=$newpath" } -pathprepend() -{ - [[ -z "$1" ]] && return 0 - local pathvar="${2:-PATH}" - [[ "$pathvar" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || { - printf "pathprepend: unsafe variable name '%s'\n" "$pathvar" >&2 - return 1 - } - pathremove "$1" "$pathvar" - export "$pathvar=$1${!pathvar:+:${!pathvar}}" -} +#pathprepend() # Unused for now, but might be useful in the future +#{ +# [[ -z "$1" ]] && return 0 +# local pathvar="${2:-PATH}" +# [[ "$pathvar" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || { +# printf "pathprepend: unsafe variable name '%s'\n" "$pathvar" >&2 +# return 1 +# } +# pathremove "$1" "$pathvar" +# export "$pathvar=$1${!pathvar:+:${!pathvar}}" +#} pathappend() { @@ -98,7 +98,7 @@ parse_conf() { local config_file="$1" local current_section="" - local line key value + local key value [[ ! -f "$config_file" ]] && return 1 @@ -140,6 +140,7 @@ parse_conf() # Use a nameref for safe, eval-free assignment local -n current_array="CONF_$current_section" + # shellcheck disable=SC2034 # Dynamic var creation current_array["$key"]="$value" fi done < "$config_file" @@ -168,6 +169,7 @@ load_alias() # Only alias if the base command is executable if command -v "$base_cmd" >/dev/null 2>&1; then + # shellcheck disable=SC2139 # Dynamic alias creation alias "$key"="$cmd" fi done @@ -204,10 +206,11 @@ load_conf() # Because we're more likely to be sourced, we use BASH_SOURCE to get the path # of the sourced file instead of $0 if [[ -z "$PROFILE_PATH" ]]; then - export MYPATH=$(dirname "$(realpath -s "${BASH_SOURCE[0]}")") + MYPATH=$(dirname "$(realpath -s "${BASH_SOURCE[0]}")") else - export MYPATH="$PROFILE_PATH" + MYPATH="$PROFILE_PATH" fi +export MYPATH if [[ ! -e "$MYPATH/profile.sh" ]]; then echo "[ Warning ] Path detection failed, trying to use pwd..." MYPATH=$(pwd) @@ -219,7 +222,8 @@ fi if [[ ! -s "$MYPATH/version" ]]; then echo "[ Warning ] Impossible to determine running version of profile, your installation might be broken." fi -export PROFVERSION=$(cat "$MYPATH"/version) +PROFVERSION=$(cat "$MYPATH"/version) +export PROFVERSION # Build PATH environment variable if [[ $EUID -eq 0 ]]; then @@ -262,7 +266,7 @@ if [[ $INTERACTIVE ]]; then # The value must match one of the alias names defined in SET_LOCALE so that # the corresponding set function exists after build_locale_shortcuts. if [[ -n "${DEFAULT_LANG:-}" ]]; then - local _lang_fn="set${DEFAULT_LANG}" + _lang_fn="set${DEFAULT_LANG}" if declare -F "$_lang_fn" >/dev/null 2>&1; then "$_lang_fn" else