Поиск по сайту:

Узнайте разницу между поиском источников и разветвлением в Bash


Основная цель этой статьи — четкое понимание того, что происходит, когда вы запускаете скрипт vs исходный код скрипта в bash. Для начала разберемся, как подается программа при вызове скрипта разными способами.

ПРИМЕЧАНИЕ: создание скрипта с расширением не имеет значения. Скрипт будет работать нормально даже без расширений.

По сути, каждый скрипт начинается со строки, называемой shebang(#!). Символ Hash в bash будет интерпретироваться как комментарий, но shebang имеет особое значение. Он сообщает bash отправить программу в любом интерпретаторе, который вы упомянули в shebang.

Ниже приведен пример программы, в качестве интерпретатора я указываю bash.

cat >> Hello_World.sh
#!/usr/bin/env bash
echo "Hello world"

chmod +x Hello_world.sh

Теперь запустить скрипт можно двумя способами.

  • Используйте относительный путь для вызова сценария. Перейдите в каталог, в котором находится скрипт, и запустите ./Hello_world.sh.
  • Используйте абсолютный путь для вызова сценария. В любом месте файловой системы введите полный путь к скрипту.
./Hello_world.sh
pwd
/home/karthick/Hello_world

Теперь давайте посмотрим, что произойдет, если вы попытаетесь отправить свою программу без shebang. При отсутствии shebang программа будет отправлена в любую текущую оболочку, в которой вы работаете. В моем случае это Bash (/bin/bash).

Позвольте мне продемонстрировать пример. Я создаю скрипт Python без shebang, и когда я вызываю программу, bash не знает, что он должен отправить эту программу интерпретатору Python, вместо этого он запустит программу в текущей оболочке.

cat > run-py.py
echo $SHELL
print("Hello world")

chmod +x run-py.py
./run-py.py

В этом случае вы можете вызвать программу, указав, в какой интерпретатор она должна быть отправлена, или просто добавить строку shebang, что всегда рекомендуется.

which python3
$(which python3) /home/karthick/run_py.py

Теперь, когда вы знаете, как вызвать сценарий, следующим шагом будет понимание того, что происходит, когда мы вызываем сценарий. Когда вы вызываете сценарий, как показано в приведенных выше примерах, он создает дочерний процесс (разветвление), и сценарий будет отправлен дочернему процессу. Я запустил пример сценария, который просто запускает следующую команду и показывает, что сценарий передается дочернему процессу.

ps -ef --forest | grep -i bash

Частью сценария может быть несколько дочерних процессов, и это зависит от нашего кода. Следует отметить, что переменные среды, созданные с помощью индекса, будут удалены после завершения работы. Дочерний процесс может получить доступ к переменным, созданным родительским процессом, путем их экспорта. Но родительский процесс не может получить доступ к переменным, созданным дочерним процессом.

Прочтите приведенные ниже статьи, чтобы узнать больше о том, как работают переменные и как их экспортировать.

  • Понимание и написание «переменных Linux» в сценариях оболочки
  • Узнайте разницу между $$и $BASHPID в Bash

Поиск сценария

«Source» — это встроенная команда оболочки, которая считывает файл, переданный ей в качестве аргумента, и запускает код в текущей среде оболочки. Подходящим вариантом использования, который вы чаще всего используете, является изменение вашей конфигурации в .bashrc или .bash_profile и перезагрузка изменений с помощью команды source.

type -a source

Существует два синтаксических способа запуска команды источника. Вы можете выбрать любой из двух синтаксисов, и это ваш личный выбор.

source FILE_NAME [ARGUMENTS]
. FILE_NAME [ARGUMENTS]

Позвольте мне продемонстрировать, как на самом деле работает источник. Я собираюсь создать два сценария оболочки. Первый скрипт (Module.sh) будет содержать некоторые переменные и функции. Второй скрипт (Main.sh) распечатает переменную и вызовет функцию.

Файл Module.sh.

#!/usr/bin/env bash

VAR1=$(echo "Welcome to $1")

function f1(){
  echo “Function f1 is called”
}

Файл Main.sh.

#!/usr/bin/env bash

echo $VAR1
f1

Установите разрешение на выполнение сценария и вызовите основной сценарий main.sh. Теперь этот скрипт попытается найти функцию f1 и переменную VAR1 в текущей среде оболочки и завершится неудачей, поскольку команда не найдена.

bash main.sh

Теперь давайте запустим исходную команду внутри скрипта, которая загрузит переменную и функции в текущую среду оболочки и будет доступна через “main.sh”.

Файл Module.sh.

#!/usr/bin/env bash

VAR1=$(echo "Welcome to $1")

function f1(){
  echo "Function f1 is called"
}

Файл Main.sh.

#!/usr/bin/env bash

source module.sh Tecmint
echo $VAR1
f1

Теперь запустите скрипт еще раз и посмотрите.

bash main.sh

Исходный код очень полезен в bash, поскольку позволяет следовать модульному подходу программирования при создании наших сценариев оболочки. Мы можем разбить наш код на более мелкие модули и использовать его во многих программах. Таким образом, мы можем следовать принципу DRY (Не повторяйся).

Вот и все, что касается этой статьи. Мы кратко обсудили разницу между поиском и разветвлением в bash. Прочтите статью и поделитесь с нами своими ценными отзывами.