В чем разница между & ldquo; источником x & rdquo ;, & ldquo ;. х & Rdquo; и & ldquo; ./ x & rdquo; в баш?

У меня есть один источник 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 исполнении.

В целом, меня интересует, почему это происходит, и в чем разница между использованием «источника» и «». для выполнения скрипта?

10
задан 8 January 2013 в 19:41

3 ответа

Прежде чем ответить, я думаю, что некоторые пояснения необходимы. Давайте проанализируем следующие три строки:

source run.sh
. run.sh
./run.sh

Первые две строки в точности совпадают: . фактически является псевдонимом для source. source выполняет сценарий оболочки в текущем контексте, поэтому вызов exit завершит работу оболочки.

Третья строка (которая вас смущает) не имеет ничего общего с другими. ./run.sh - это просто путь, и он такой же, как (например) /home/user/run.sh или /usr/bin/something. Всегда помните, что команды в оболочке разделяются пробелом. Таким образом, в этом случае команда не ., а ./run.sh: это означает, что будет выполнена суб-оболочка и что exit будет действовать только на эту суб-оболочку.

0
ответ дан 8 January 2013 в 19:41

Три способа:

Вы можете заключить скрипт в функцию и использовать только 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
0
ответ дан 8 January 2013 в 19:41

Думайте о команде «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 с символом «.» представляющий вашу текущую папку.

0
ответ дан 8 January 2013 в 19:41

Другие вопросы по тегам:

Похожие вопросы: