Проверка, запущен ли скрипт в терминале или источнике: полезное руководство
В вашем процессе разработки может возникнуть необходимость определить, запущен ли ваш Bash-скрипт в терминале или вызывается из другого скрипта. Эта информация может быть критически важной для правильного функционирования вашего приложения. В этой статье мы рассмотрим, как создать тестовый скрипт, который проверяет режим запуска и выводит соответствующий результат.
Определение целей и тестовых случаев
Для начала нам необходимо определить наши цели. Мы хотим знать:
- Выполняется ли скрипт в терминале или нет.
- Запущен ли скрипт непосредственно пользователем или вызывается из другого скрипта.
Это обозначает, что у нас есть четыре основных тестовых случая:
- Запуск в терминале и не в источнике.
- Запуск в терминале и в источнике.
- Запуск не в терминале и не в источнике.
- Запуск не в терминале и в источнике.
Основной скрипт проверки
Создадим основной скрипт проверки, который будет обрабатывать эти условия. Вот его содержание:
#!/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-скрипт в терминале или вызван из другого скрипта. Используя предложенные тестовые случаи и основной скрипт проверки, вы можете легко управлять поведением ваших скриптов в зависимости от режима их выполнения. Эта информация будет полезна для улучшения ваших скриптов и оптимизации рабочего процесса. Не забывайте тестировать свои скрипты в различных условиях, чтобы убедиться, что они работают корректно.