Как вызвать сценарий оболочки из другого сценария оболочки?

356

У меня есть два сценария оболочки, a.sh и b.sh.

Как я могу вызвать b.sh из оболочки script a.sh?

  • 8
    Можете ли вы дать некоторые подробности: какую ОС и какую оболочку (и) или вы просто говорите об этой проблеме в принципе ?? Пример кода также будет полезен.
  • 12
    Это на самом деле не конкретный вопрос, и при этом он не демонстрирует предварительных усилий по решению проблемы.
Показать ещё 3 комментария
Теги:

13 ответов

584

Есть несколько способов сделать это:

  • Сделайте другой исполняемый файл script, добавьте строку #!/bin/bash вверху и путь, где файл относится к переменной среды $PATH. Затем вы можете вызвать его как обычную команду.

  • Вызовите его командой source (псевдоним .) следующим образом: source /path/to/script.

  • Используйте команду bash для ее выполнения: /bin/bash /path/to/script.

Первый и третий методы выполняют script как еще один процесс, поэтому переменные и функции в другом script не будут доступны.
Второй метод выполняет script в первом процессе script и вытягивает переменные и функции из другого script, поэтому они могут использоваться из вызывающего script.

Во втором методе, если вы используете exit во втором script, он также выйдет из первого script. Что не произойдет в первом и третьем методах.

  • 22
    не забудьте chmod a+x /path/to/file иначе он не будет исполняемым. Относится только к методу ./script.
  • 3
    Не забудьте изменить формат / кодировку исполняемых файлов в Unix, если они созданы в DOS, а затем загружены в среду Unix -> dos2unix <имя скрипта>
Показать ещё 9 комментариев
133

Проверьте это.

#!/bin/bash
echo "This script is about to run another script."
sh ./script.sh
echo "This script has just run another script."
  • 0
    как указать путь?
  • 4
    Это предполагает, что script.sh находится в том же каталоге, что и любой другой скрипт. Если вы хотите вызвать скрипт в другом месте, вы должны сказать sh <path to script>/script.sh
Показать ещё 2 комментария
39

Ответ, который я искал:

( exec "path/to/script" )

Как уже упоминалось, exec заменяет оболочку без создания нового процесса. Однако, мы можем поместить его в подоболочку, что делается с помощью скобок.

EDIT: На самом деле ( "path/to/script" ) достаточно.

  • 7
    Это кажется довольно запутанным. Почему бы просто не вызвать его с помощью /path/to/script ? Я вообще не вижу необходимости в exec ?
  • 0
    @Carpetsmoker, ты очень прав! изм.
Показать ещё 4 комментария
21

Есть несколько способов сделать это. Терминал для выполнения 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")

Все это правильно для пути с пробелами!!!

  • 30
    Каковы их различия? Почему один, почему другой?
  • 0
    , "$ SCRIPT_PATH" является предпочтительным
Показать ещё 1 комментарий
11

Зависит от. Кратко... Если вы хотите, чтобы переменные нагрузки на текущей консоли и выполнялись, вы можете использовать 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

Надеюсь, вам помогут. Спасибо.

  • 2
    Обратите внимание, что source - это особенность Bash. Стандартная оболочка Bourne имеет только . (например, . other_script.sh ).
11

Вы можете использовать /bin/sh для вызова или выполнения другого script (через ваш фактический script):

 # 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
  • 1
    Конечно, это будет запускать showdate.sh в / bin / sh, а не в / bin / bash?
  • 0
    я попытался с " /bin/sh ./showdate.sh ", " /bin/bash ./showdate.sh ", " ./showdate.sh " и запустил файл: mainscript.sh и получил тот же вывод.
7

Просто добавьте строку, которую вы бы набрали в терминале, чтобы выполнить script!
например:.

#!bin/bash
./myscript.sh &

если выполняемый script не находится в одном каталоге, просто используйте полный путь к script.
например: `/home/user/ script-directory/./myscript.sh &

  • 0
    Зачем добавлять & ?
  • 0
    @Carpetsmoker & для фоновой задачи
6

Сначала вы должны включить файл, который вы вызываете:

#!/bin/bash
. includes/included_file.sh

то вы вызываете свою функцию следующим образом:

#!/bin/bash
my_called_function
3
pathToShell="/home/praveen/"   
chmod a+x $pathToShell"myShell.sh"
sh $pathToShell"myShell.sh"
2
 #!/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=$?
  • 1
    неверно для папки scriptPath или имени файла scriptName с пробелами
2

Предположим, что новый файл "/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 в командной строке.

1

Простой источник поможет вам. Для примера

#!/bin/bash
echo "My shell_1"
source my_script1.sh
echo "Back in shell_1"
0

Есть некоторые проблемы для импорта функций из другого файла.
Первый: вам не нужно выполнять этот файл. Лучше не делать этого! просто добавьте

. file

чтобы импортировать все функции. И все они будут, как если бы они были определены в вашем файле.
Второй. Вы можете определить функцию с тем же именем. Он будет перезаписан. Это плохо. Вы можете так заявить

declare -f new_function_name=old_function_name 

и только после этого импортировать. Таким образом, вы можете назвать старую функцию новым именем.
Третий. Вы можете импортировать только полный список функций, определенных в файле. Если некоторые из них не нужны, вы можете их отключить. Но если вы перезапишете свои функции после их отмены, они будут потеряны. Но если вы установите ссылку на него, как описано выше, вы можете восстановить ее после того, как она не установлена ​​с тем же именем.
Наконец В общей процедуре импорта опасно и не так просто. Быть осторожен! Вы можете написать script, чтобы сделать это более простым и безопасным. Если вы используете только часть функций (не все), лучше разделить их в разных файлах. К сожалению, этот метод не преуспел в bash. В python например и некоторых других языках script это легко и безопасно. Можно сделать частичный импорт только необходимыми функциями со своими именами. Мы все хотим, чтобы в следующих версиях куста была сделана такая же функциональность. Но теперь мы должны написать много дополнительной трески, чтобы делать то, что вы хотите.

  • 0
    (Добро пожаловать в SO!) Поскольку пользователя Praveen в последний раз видели в 2011 году, непросто будет выяснить, был ли вопрос, как заставить оболочку, выполняющую a.sh, выполнить b.sh (и продолжить выполнение a.sh, если нет приказал иначе ) или буквально вызывать б.ш. (Моя программа проверки орфографии не bush versions .) (У вас есть кто-то, к кому можно обратиться, чтобы помочь вам с грамматикой английского языка? (Иногда хотелось бы, чтобы у меня было.))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню