Search code examples
linuxbashshellshshebang

Bash script lost shebang path after instantiate function


I am writing a script with a iterative menu to run command lines. However, after create the iterative menu I got a error when I want run the commands. The error is [COMMAND]No such file or directory linux.

#!/bin/bash
ATESTS=("TEST NAME 1" "TESTE NAME 2")
PATH=("test1.xml" "text2.xml")

menu () {
   for i in ${!ATESTS[@]}; do
       printf "%3d%s) %s\n" $((i+1)) "${OPT[i]:- }" "${ATESTS[i]}"
   done
   [[ "$msg" ]] &&  echo "$msg"; :
}

prompt="Check an ATEST (again to uncheck, ENTER when done): "

while menu && read -rp "$prompt" num && [[ "$num" ]]; do
    /usr/bin/clear;
    [[ "$num" != *[![:digit:]]* ]] &&
    (( num > 0 && num <= ${#ATESTS[@]} )) ||
    { msg="Invalid ATEST: $num"; continue; }
    ((num--)); msg="${ATESTS[num]} was ${OPT[num]:+un}checked"
    [[ "${OPT[num]}" ]] && OPT[num]="" || OPT[num]="+"
done

for i in ${!ATESTS[@]}; do
    [[ "${OPT[i]}" ]] && { printf "%s " "${ATESTS[i]}"; msg=""; }
done

echo "$msg"

for i in ${!ATESTS[@]}; do
   if [[ "${OPT[i]}" ]] && [[ $PWD = /repo/$USER/program ]]; then
       find . -iname ${PATH[i]} -exec cat {} \;
   fi
done

I want find a *.xml file then execute with a script that already exist and belong to /usr/bin. However the find command dont execute and also the cat command in this example, getting the following error ([COMMAND]No such file or directory linux.)

if i try run one bash command before the function, the command execute without any problem, but after the function the commands fails.

I create one alias to the script for running inside /repo/$USER/program without include the path to the script.


Solution

  • The problem has nothing to do with the shebang or the function. The problem is that you're using the variable $PATH. This variable tells the system what directories to search for executable commands, so when you set it to an array... it's going to start looking for commands in the locations(s) specified by ${PATH[0]}, which is "test1.xml", which is not even a directory let alone one that contains all of the executables you need.

    Solution: don't use the variable name PATH for anything other than the list of directories to search for commands. In fact, since this is one of a large number of all-uppercase variables that have special functions, it's best to use lowercase (or mixed-case) variables in your scripts, to avoid weird conflicts like this.

    BTW, I can't tell if the rest of the script makes sense or not; your use of short-circuit booleans for conditional execution (e.g. this && that || do something) makes it really hard to follow the logic. I'd strongly recommend using if blocks for conditional execution (as you did in the for loop at the end); they make it much easier to tell what's going on.