Тадам! Сегодня научимся определять, отправляется ли стандартный вывод скрипта в терминал либо передаётся с помощью pipe в другой скрипт/утилиту. Чтобы стало понятнее, нужно читать дальше.

Есть у меня некий Bash-скрипт, пусть будет таким:

echo "Hello Bashdays Welcome"

Если его выполнить, то на экран выведется ожидаемый результат. Но что, если я хочу добавить логику в этот скрипт, которая будет детектить pipe и отдавать другой ожидаемый результат?

Давай по порядку, смотри:

bold=$(tput bold)
normal=$(tput sgr0)

echo "Hello ${bold}BashDays${normal} Welcome"

Этот скрипт выведет строку Hello Bashdays Welcome, где слово Bashdays будет жирным (bold).

Дальше я хочу, чтобы при использовании pipe слово BashDays НЕ выделялось жирным. То есть если запустить скрипт самостоятельно, без использования пайпов, то текст будет жирным. Если скрипт запущен через пайп, то текст остаётся нормальный.

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

Давай мутить

В POSIX-оболочках существует флаг -t, с помощью которого можно задетектить файловый дескриптор. Если файловый дескриптор fd = True, то скрипт запущен самостоятельно в терминале. Дескриптор fd может принимать значения:

0 - стандартный ввод
1 - стандартный вывод
2 - стандартная ошибка

Пишем скрипт с логикой:

bold=$(tput bold)
normal=$(tput sgr0)

if [ -t 1 ] ; then
    echo "Hello ${bold}BashDays${normal} Welcome"
else
    echo "Hello BashDays Welcome"
fi

Запускаем:

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

Флаг -t справедлив не только для Bash, он будет работать во всех POSIX-оболочках.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Вот такие вот интересные кейсы порой приходится решать, благо всё это давно придумано за нас, главное знать про эту срань. Ну теперь и ты про неё знаешь.

Хорошего дня, увидимся!