Думайте о команде «source» как в «include». Он берет содержимое аргумента и запускает его так, как если бы он был запущен напрямую. В этом случае ваша команда 'source' с аргументом 'run.sh', а run.sh выполняется точно так же, как если бы вы ввели содержимое run.sh в вашу командную строку.
Когда вы запускаете «./run.sh», «./run.sh» является вашей командой и не имеет аргументов. Поскольку этот файл является обычным текстом, а не двоичным, ваша оболочка ищет интерпретатор в shebang ('#!' В первой строке) и находит '/ bin / bash'. Таким образом, ваша оболочка затем запускает новый экземпляр bash, и содержимое run.sh запускается внутри этого нового экземпляра.
В первом случае, когда bash достигает команды exit, она выполняется точно так же, как если бы вы ввели ее в командную строку. Во втором случае это выполняется в процессе bash, который запустила ваша оболочка, поэтому только этот экземпляр bash получает команду 'exit'.
Когда вы вводите строку в bash, все, что находится перед первым пробелом, обрабатывается как команда, а все последующее - как аргументы. Команда '.' является псевдонимом «источник». Когда ты бежишь ». run.sh 'the'. ' это отдельная команда, так как она отделена от аргументов пробелом. Когда вы запускаете «./run.sh», ваша команда «./run.sh» и «.» является частью относительного пути к run.sh с символом «.» представляющий вашу текущую папку.
$- = *i*
работает магическое заклинание ?