简体   繁体   中英

Tab-indented if statement fails on command line but works in bash script

I write my scripts in a text editor using tabs for indentation as it is easier to type 1 Tab than 4 Space . However, I just drove myself nuts trying to figure out why the if statement below, which works in my bash script, fails to work on the command line:

dirs=(HIC11490 HIC11493 HIC11494)
for i in "${dirs[@]}"; do
    if [ -d "$i" ]; then 
        echo $i exists; 
    else 
        echo $i does not exist;
    fi
done

Specifically, it lists all of the files in the working directory:

$ nums=(HIC11490 HIC11493 HIC11494)
$ for i in "${nums[@]}"; do
> if [ -d "$i" ]; then
>
Display all 13526 possibilities? (y or n)
14295291/                                    HIC3958/
AG25/                                        HIC3959/
AG36/                                        HIC3969/
AG48_Aleksei/                                HIC397/
BGS-11/                                      HIC3970/
BSCC/                                        HIC3971/
  .                                            .
  .                                            .
  .                                            .
DNA128/                                      HIC4465/
DNA129/                                      HIC4466/
> ot exist;
> fi
> done
-bash: ot: command not found
-bash: ot: command not found
-bash: ot: command not found

Turns out, the tabs were the problem, and the code works from the command line if they are replaced with spaces.

Are there any other characters that behave differently in bash scripts than on the command line that I should be aware of? Thanks.

Sending tab to bash triggers autocompletion. Two tab characters trigger showing all possible completions. Bash sees that you started typing for i in "${nums[@]}"; do for i in "${nums[@]}"; do and then two tab trigger autocompletion. In this case because no match to a registered completion are found, most autocompletion scripts then list all files in the current directory. If the list is longer then some length, a Display all 13526 possibilities? question is displayed. Then characters are read from the input to answer the Display all 13526 possibilities? (y or n) Display all 13526 possibilities? (y or n) part (ie. the echo will be passed as an answer to this question...) and the script falls apart.

This is all configurable. Bash uses GNU readline library for reading what you type and the library handles (parts) of autocompletion.

To answer the second part of your question (since the first has been answered already by KamilCuk), other characters which you should be aware of, are # and ! .

In scripts (non-interactive shells), a # introduces a comment, while in an interactive shell, you can configure, whether or not this is the case, or whether a hash should be treated as valid character at the start of a command. This is controlled by the interactive_comments setting of shopt .

In interactive shells, ! introduces history substitution (ie !$ is replaced by the last argument of the most recent command). This substitution does not occur in a bash script.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM