Antes de responder, acho que alguns esclarecimentos são necessários. Vamos analisar as três linhas seguintes:
source run.sh
. run.sh
./run.sh
As duas primeiras linhas são exatamente idênticas: . é, na verdade, um alias para source . O que source faz é executar o script de shell no contexto atual, portanto, uma chamada para exit irá encerrar o shell.
A terceira linha (que é aquela que confunde você) não tem nada a ver com as outras linhas. ./run.sh é apenas um caminho e é o mesmo que (por exemplo) /home/user/run.sh ou /usr/bin/something . Lembre-se sempre de que os comandos no shell estão separados por um espaço. Então, neste caso, o comando não é . , mas é ./run.sh : isso significa que um sub-shell será executado e que o exit terá efeito apenas para o sub-shell.