1

Here is my code:

#!/bin/bash 
if [[ $1 = "" ]]; then
    exit 0
fi
array=($(cat $1))
let b=${#array[@]}-1
count=0
for i in {1..7}; do
    for j in {30..37}; do
        for n in {40..47}; do
            if [[ $count -gt $b ]]; then
                printf '\n'
                printf '\e[0m'
                exit 1
            fi
            printf '\e[%s;%s;%sm%-5s' "$i" "$j" "$n" "${array[$count]}"
            printf '\e[0m'
            let count=$count+1
        done
        printf '\n'
    done
done
#printf '\n'
printf '\e[0m'
exit 0

The problem is that when I start it like this

. color.sh arg

or without argument, it just closes. I know that the reason for that is exit. Is there any way correct my code so I could start a script with dot at start and terminal wouldn't close after execution? I don't want to start it like this: ./script

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
Mak
  • 91
  • 9
  • 2
    Remove the `exit`? – choroba Dec 03 '18 at 14:46
  • 1
    How about not calling `exit` ?! – Corion Dec 03 '18 at 14:47
  • Both of you are forgetting that there are multiple `exit`s inside `if`s. – Socowi Dec 03 '18 at 14:49
  • If your purpose is to source the file (https://ss64.com/bash/source.html) and if you use exit it will definitely close the current shell.Options available are : 1. Don't use exit in the script 2.Don't source the file but execute it directly. – kishs1991 Dec 03 '18 at 15:07
  • See also [How to detect if a script is being sourced](https://stackoverflow.com/q/2683279/7552) and [bash: exit from source-d script](https://stackoverflow.com/questions/49857332/bash-exit-from-source-d-script) – glenn jackman Dec 03 '18 at 15:45

2 Answers2

5

Replace all exit with return. return inside a sourced script will even work with exit codes:

$ . <(echo "echo before; return 0; echo after")
before
$ echo $?
0
$ . <(echo "echo before; return 7; echo after")
before
$ echo $?
7
Socowi
  • 25,550
  • 3
  • 32
  • 54
2

When you use the dot to run a script you are "sourcing" it, which means the interpreter reads and executes all the commands in that script in the context of the current environment without spawning a subshell, as if you had typed each yourself.

That's why if you source it you can set variables in a script that will remain after it has run, whereas running it in a subshell would encapsulate them, and they would go away when the script ends.

Accordingly, if you source a script that hits an exit, it causes the calling environment to exit. Use return as Socowi suggested.

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36