У меня есть два сценария оболочки, a.sh
и b.sh
.
Как я могу вызвать b.sh
из скрипта оболочки a.sh
?
Есть несколько способов сделать это:
Сделайте другой сценарий исполняемым, добавьте строку #!/bin/bash
вверху и путь к файлу к переменной среды $ PATH. Тогда вы можете вызвать его как обычную команду;
Или вызовите его с помощью команды source
(псевдоним .
), например: source /path/to/script
;
Или используйте команду bash
для ее выполнения: /bin/bash /path/to/script
;
Первый и третий методы выполняют скрипт как другой процесс, поэтому переменные и функции в другом скрипте не будут доступны.
Второй метод выполняет сценарий в процессе первого сценария и извлекает переменные и функции из другого сценария, чтобы их можно было использовать из вызывающего сценария.
Во втором методе, если вы используете exit
во втором скрипте, он также выйдет из первого скрипта. Что не произойдет в первом и третьем способах.
Проверь это.
#!/bin/bash
echo "This script is about to run another script."
sh ./script.sh
echo "This script has just run another script."
Есть несколько способов сделать это. Терминал для выполнения скрипта:
#!/bin/bash
SCRIPT_PATH="/path/to/script.sh"
# Here you execute your script
"$SCRIPT_PATH"
# or
. "$SCRIPT_PATH"
# or
source "$SCRIPT_PATH"
# or
bash "$SCRIPT_PATH"
# or
eval '"$SCRIPT_PATH"'
# or
OUTPUT=$("$SCRIPT_PATH")
echo $OUTPUT
# or
OUTPUT=`"$SCRIPT_PATH"`
echo $OUTPUT
# or
("$SCRIPT_PATH")
# or
(exec "$SCRIPT_PATH")
Все это правильно для пути с пробелами !!!
Ответ, который я искал:
( exec "path/to/script" )
Как уже упоминалось, exec
заменяет оболочку без создания нового процесса. Однако , мы можем поместить это в подоболочку, что делается с помощью парантезов.
Правка: На самом деле ( "path/to/script" )
достаточно.
Вы можете использовать /bin/sh
для вызова или выполнения другого скрипта (через ваш реальный скрипт):
# cat showdate.sh
#!/bin/bash
echo "Date is: `date`"
# cat mainscript.sh
#!/bin/bash
echo "You are login as: `whoami`"
echo "`/bin/sh ./showdate.sh`" # exact path for the script file
Результат будет:
# ./mainscript.sh
You are login as: root
Date is: Thu Oct 17 02:56:36 EDT 2013
Зависит от . Кратко ... Если вы хотите загрузить переменные на текущей консоли и выполнить, вы можете использовать source myshellfile.sh
в своем коде. Пример:
!#/bin/bash
set -x
echo "This is an example of run another INTO this session."
source my_lib_of_variables_and_functions.sh
echo "The function internal_function() is defined into my lib."
returned_value=internal_function()
echo $this_is_an_internal_variable
set +x
Если вы просто хотите выполнить файл, и единственное, что вас интересует - это результат, вы можете сделать:
!#/bin/bash
set -x
./executing_only.sh
sh i_can_execute_this_way_too.sh
bash or_this_way.sh
set +x
Я надеюсь, что поможет вам .... Спасибо.
Просто добавьте в строку все, что вы набрали бы в терминале, чтобы выполнить скрипт!
например.:
#!bin/bash
./myscript.sh &
если скрипт, который нужно выполнить, не находится в той же директории, просто используйте полный путь скрипта.
Например ::`/home/user/script-directory/./myscript.sh &
Простой источник поможет вам . Например.
#!/bin/bash
echo "My Shell_1"
source my_script1.sh
echo "Back in Shell_1"
Сначала вы должны включить файл, который вы называете:
#!/bin/bash
. includes/included_file.sh
тогда вы вызываете свою функцию так:
#!/bin/bash
my_called_function
pathToShell="/home/praveen/"
chmod a+x $pathToShell"myShell.sh"
sh $pathToShell"myShell.sh"
#!/bin/bash
# Here you define the absolute path of your script
scriptPath="/home/user/pathScript/"
# Name of your script
scriptName="myscript.sh"
# Here you execute your script
$scriptPath/$scriptName
# Result of script execution
result=$?
Предположим, что новый файл "/ home/satya/app/app_specific_env" и содержимое файла выглядит следующим образом
#!bin/bash
export FAV_NUMBER="2211"
Добавить ссылку на этот файл в файл ~/.bashrc
source /home/satya/app/app_specific_env
Каждый раз, когда вы перезагружаете машину или перезагружаетесь, попробуйте echo $FAV_NUMBER
в терминале. Это выведет значение.
На всякий случай, если вы хотите увидеть эффект сразу, source ~/.bashrc
в командной строке.
chmod a+x /path/to/file-to-be-executed
Это было единственное, что мне было нужно. Когда выполняемый скрипт становится исполняемым, как это, вам (по крайней мере, в моем случае) не нужны никакие другие дополнительные операции, такие как sh
или ./
, когда вы вызываете скрипт.
Благодаря комментарию @Nathan Lilienthal
Используйте backticks.
$ ./script-that-consumes-argument.sh `sh script-that-produces-argument.sh`
Затем извлеките выходные данные сценария производителя в качестве аргумента сценария потребителя.
Верхний ответ предполагает добавление строки #!/bin/bash
в первую строку вызываемого подпрограммы. Но даже если вы добавите Шебанг, это намного быстрее* запустить скрипт в суб-оболочке и записать вывод:
$(source SCRIPT_NAME)
Это работает, когда вы хотите продолжать работать с одним и тем же интерпретатором (например, от bash до другого сценария bash) и гарантирует, что строка Shebang подпрограммы не будет выполнена.
Например:
#!/bin/bash
SUB_SCRIPT=$(mktemp)
echo "#!/bin/bash" > $SUB_SCRIPT
echo 'echo $1' >> $SUB_SCRIPT
chmod +x $SUB_SCRIPT
if [[ $1 == "--source" ]]; then
for X in $(seq 100); do
MODE=$(source $SUB_SCRIPT "source on")
done
else
for X in $(seq 100); do
MODE=$($SUB_SCRIPT "source off")
done
fi
echo $MODE
rm $SUB_SCRIPT
Результат:
~ ❯❯❯ time ./test.sh
source off
./test.sh 0.15s user 0.16s system 87% cpu 0.360 total
~ ❯❯❯ time ./test.sh --source
source on
./test.sh --source 0.05s user 0.06s system 95% cpu 0.114 total
* Например, когда на устройстве запущены средства защиты от вирусов или вирусов, для запуска нового процесса могут потребоваться дополнительные 100 мс.
Есть проблемы с импортом функций из другого файла.
Первый : Вам не нужно делать этот файл исполняемым. Лучше не делать этого! Просто добавьте
. file
импортировать все функции. И все они будут, как если бы они были определены в вашем файле.
Второй : Вы можете определить функцию с тем же именем. Это будет перезаписано. Это плохо. Вы можете заявить, что так
declare -f new_function_name=old_function_name
и только после этого выполните импорт . Таким образом, вы можете вызывать старую функцию под новым именем.
Третий : Вы можете импортировать только полный список функций, определенных в файле . Если некоторые из них не нужны, вы можете отменить их. Но если вы переписываете свои функции после сброса, они будут потеряны. Но если вы установите ссылку на него, как описано выше, вы можете восстановить после сброса с тем же именем.
Наконец В общем процедура импорта ввоза опасна и не так проста. Быть осторожен! Вы можете написать скрипт, чтобы сделать это более простым и безопасным .. Если вы используете только часть функций (не все), лучше разбейте их на разные файлы. К сожалению, эта техника не очень хорошо работает в Bash. Например, в python и некоторых других языках сценариев это просто и безопасно. Возможен частичный импорт только необходимых функций со своими именами. Мы все хотим, чтобы в следующих версиях куста была сделана та же функциональность. Но теперь мы должны написать много дополнительных кодов, чтобы делать то, что вы хотите.