Вы проверяете его параметры.
[ "$-" = "${-#*i}" ] ||
echo shell is interactive
Вы также можете проверить его файловые дескрипторы. Это немного другое. Он не обязательно скажет вам, является ли оболочка интерактивной как таковой, но он сообщит вам, общается ли она с терминалом.
for fd in 0 1 2
do [ -t "$fd" ] &&
break
done|| echo shell fds 0 1 2 are not connected to a terminal.
Мы можем немного взломать это, чтобы попытаться обнаружить все используемые процессы нашего терминала.
tty_users()
for fd in 0 1 2 "$@"
do [ -t "$fd" ] && {
fuser "$(tty)"
break; } <&"$fd"
done
Которая будет запущена в текущей оболочке и распечатает список идентификаторов процессов для тех процессов, которые запущены на первом обнаруженном терминале, как связанные с std (in | out | err)
(по умолчанию - передать функцию числовые аргументы для проверки других) соответственно. Он устанавливает для оболочки var $ fd
номер дескриптора файла, связанный с этим терминалом, и возвращает false, если ни один из стандартных дескрипторов или каких-либо аргументов не связан с терминалом.
Вышеупомянутое, вероятно, так близко, как вы получите, если вы не поищете идентификатор сеанса вашего терминала - если он у вас есть.
ps -osid= -p"$$"
Это вернет вам pid владельца вашего управляющего терминала - если он у вас есть.
Чтобы продемонстрировать:
echo "$$"; sh -c 'sh -c "ps -osid= -p\"\$$\""'
6023
6023
Но вы не можете полагаться ни на что из этого. Вовсе нет. Смотрите:
sh -acm 'IFS=\; i=0;eval "$0"' \
'[ "$i" -lt 5 ] && eval "$*"' \
'ps -opid -opgid -p"$$"' \
'sh -acm "$0" "$0" "$@" i=$((i+=1))'
PID PGID
28766 28766
PID PGID
28768 28768
PID PGID
28770 28770
PID PGID
28772 28772
PID PGID
28774 28774
Видите? Интерактивной оболочки, из которой я запускаю эти процессы, нет даже в этом списке. Каждый sh
запускает собственный дочерний элемент, пока не будет достигнута глубина 5, и при каждом запуске вызывает ps
для печати своего PID и PGID. Каждый процесс получает новый PGID. Управление заданиями так же связано с интерактивной оболочкой, как и терминал, просто терминал - это более прямой способ проверить это.
\1
будет ссылаться на первую группу захвата. Поскольку в настоящее время у вас нет группы захвата, вы можете определить совпадение как группу захвата, окружив его фигурными скобками и сославшись на него, используя\1
:
$ echo 1 | sed 's/\(.*\)/(\1)/'
(1)
&
— это стандартный способ замены всего совпадения с образцом.Некоторые реализации sed
, такие как GNU или busybox, поддерживают \0
в качестве альтернативы, но это не стандартно и не переносимо.
$ echo 1 | sed -e 's/.*/(&)/'
(1)
Эта команда заключает в скобки первую (возможно пустую )последовательность из символов , как можно больше в каждой строке. Это может не включать полную строку для тех строк, которые содержат байты, не образующие допустимые символы, и в этом случае вы можете обнаружить, что:
sed 's/^/(/; s/$/)/'
Работает более надежно, заключая полную строку в круглые скобки.