У меня есть один источник bash run.sh
, как показано ниже:
#!/bin/bash
if [ $# -ne 1 ]; then
exit
fi
...
, , когда я выполняю его двумя способами, существуют разные варианты поведения. Первый способ:
source run.sh
Он закроет терминал после выполнения. Второй способ,
./run.sh
, он просто завершит выполнение скрипта и останется на терминале. Я спрашиваю, есть ли команда для выхода из скриптов bash для выполнения source run.sh
и ./run.sh
. Я тоже пробовал return
, что не очень хорошо работает при ./run.sh
исполнении.
В целом, меня интересует, почему это происходит, и в чем разница между использованием «источника» и «». для выполнения скрипта?
Прежде чем ответить, я думаю, что некоторые пояснения необходимы. Давайте проанализируем следующие три строки:
source run.sh
. run.sh
./run.sh
Первые две строки в точности совпадают: .
фактически является псевдонимом для source
. source
выполняет сценарий оболочки в текущем контексте, поэтому вызов exit
завершит работу оболочки.
Третья строка (которая вас смущает) не имеет ничего общего с другими. ./run.sh
- это просто путь, и он такой же, как (например) /home/user/run.sh
или /usr/bin/something
. Всегда помните, что команды в оболочке разделяются пробелом. Таким образом, в этом случае команда не .
, а ./run.sh
: это означает, что будет выполнена суб-оболочка и что exit
будет действовать только на эту суб-оболочку.
Три способа:
Вы можете заключить скрипт в функцию и использовать только return.
#!/usr/bin/env bash
main() {
...
return 1
...
}
main "$@"
Вы можете проверить, использует ли скрипт интерактивную оболочку.
if [[ $- = *i* ]]; then
return 1
else
exit 1
fi
Вы можете попытаться вернуться, а если ничего не получится, выйти.
return 1 2>/dev/null || exit 1
Думайте о команде «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 с символом «.» представляющий вашу текущую папку.