Проверка запуска сценария внутри другого сценария: пошаговое руководство

Проверка, запущен ли скрипт в терминале или источнике: полезное руководство

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

Определение целей и тестовых случаев

Для начала нам необходимо определить наши цели. Мы хотим знать:

  1. Выполняется ли скрипт в терминале или нет.
  2. Запущен ли скрипт непосредственно пользователем или вызывается из другого скрипта.

Это обозначает, что у нас есть четыре основных тестовых случая:

  • Запуск в терминале и не в источнике.
  • Запуск в терминале и в источнике.
  • Запуск не в терминале и не в источнике.
  • Запуск не в терминале и в источнике.

Основной скрипт проверки

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

#!/usr/bin/env bash

IS_TERMINAL=true
NOT_TERMINAL=false
TEST_NUM=0
SOURCED_TEXT="undefined"

print_result() {
  TEST_NUM=$((TEST_NUM + 1))
  if [ "$1" = "$IS_TERMINAL" ]; then
    printf "%2d: %-16s %-12s %s\n" "$TEST_NUM" "in terminal:" "$SOURCED_TEXT:" "$2"
  else
    printf "%2d: %-16s %-12s %s\n" "$TEST_NUM" "not in terminal:" "$SOURCED_TEXT:" "$2"
  fi
}

# Проверяем, запущен ли скрипт из внешнего источника
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  SOURCED_TEXT="not sourced"
else
  SOURCED_TEXT="sourced"
fi

# Запускаем тесты
if [ -t 0 ]; then
    print_result "$IS_TERMINAL" "stdin is a terminal"
else
    print_result "$NOT_TERMINAL" "stdin is not a terminal"
fi

if [ -t 1 ]; then
    print_result "$IS_TERMINAL" "stdout is a terminal"
else
    print_result "$NOT_TERMINAL" "stdout is not a terminal"
fi

if [ -t 2 ]; then
    print_result "$IS_TERMINAL" "stderr is a terminal"
else
    print_result "$NOT_TERMINAL" "stderr is not a terminal"
fi

if [[ "$-" == *i* ]]; then
    print_result "$IS_TERMINAL" "interactive shell"
else
    print_result "$NOT_TERMINAL" "non-interactive shell"
fi

if [ -n "$(tty)" ]; then
    print_result "$IS_TERMINAL" "has a controlling terminal"
else
    print_result "$NOT_TERMINAL" "does not have a controlling terminal"
fi

if [ -p /dev/stdin ]; then
    print_result "$NOT_TERMINAL" "running in a pipeline"
else
    print_result "$IS_TERMINAL" "not running in a pipeline"
fi

if [ -z "$(jobs -p)" ]; then
    print_result "$IS_TERMINAL" "running in foreground"
else
    print_result "$NOT_TERMINAL" "running in background"
fi

# Получаем ID родительского процесса
PPID_VALUE=$(ps -o ppid= -p $$ | awk 'NR==2 {print $1}')

# Проверяем, прикреплен ли процесс
if [ "$PPID_VALUE" -ne 1 ]; then
    print_result "$IS_TERMINAL" "attached to a parent process"
else
    print_result "$NOT_TERMINAL" "detached from a parent process"
fi

# Проверяем, является ли родительский процесс шеллом
PARENT_CMD=$(ps -o args= -p "$PPID_VALUE" 2>/dev/null)
if echo "$PARENT_CMD" | grep -qE '/(bash|zsh|sh)(\s|$)'; then
    print_result "$IS_TERMINAL" "parent process is a shell"
else
    print_result "$NOT_TERMINAL" "parent process is not a shell"
fi

Скрипт-водитель

Теперь создадим скрипт-водитель, который запустит наш основной скрипт проверки.

#!/usr/bin/env bash

./check-term
echo ""
. ./check-term

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

Заключение

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

Источник

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *