«Управляющий терминал» aka. CTTY, отличается от « терминала . Процесс взаимодействует с«.
Стандартный способ получения пути CTTY является Ctermid (3). Позвонив этому, в FreeBSD с релиза 10, фактический путь выглядит [1], В то время как более старые FreeBSD и реализации GLIBC [2] безоговорочно возвращаются «/ dev / tty»].
PS (1) из пакета Linux PRECPS 3.2.8, Прочитайте численную запись в / proc / * / stat [3], а затем вычитают путь частично, догадаясь [4, 5] из-за отсутствия поддержки системы [6].
Однако, если мы не строго заинтересованы в CTTY, но любой терминал, связанный со Stdio, Tty (1), отпечатывает терминальный путь, подключенный к stdin, который идентичен TtyName (FileNO (stdin))
C и альтернатива ReadLink / Proc / Self / Fd / 0
.
Менее важная мысль в отношении безусловного поведения «/ dev / tty»: спецификации просто говорят строку, возвращаемую ctermid "при использовании в качестве имени пути, обратитесь к текущему управлению терминалу«, а не какой-то простой »- это имя пути текущего контролирующего терминала ". Это может быть интерпретировано как «/ dev / tty» не является контролирующим терминалом, но относится только к контролирующему терминалу, если тот же процесс открывается (3). Таким образом, не нарушать «Терминал может быть CTTY для не более одного сеанса« Правило [7].
Другое следствие, что когда я без какого-либо контролирующего терминала, Ctermid не сработает - Такое провал разрешено спецификациями [8] - так или только я могу стать осознать мою CTTY, пока не удастся Последующий открытый (3), который в порядке, поскольку спецификации также говорят, что вызывает открытую (3) на нем, не является Guarranted, чтобы добиться успеха.
Спецификация POSIX действительно хеджирует свои ставки, когда речь идет о Управляющем терминале , который определяется таким образом:
/ dev / tty
является синонимом управляющего терминала, связанного с процессом. Это в списке определений - и это все, что там есть. Но в Общий интерфейс терминала сказано еще несколько:
Терминал может принадлежать процессу как его управляющий терминал. Каждый процесс сеанса, который имеет управляющий терминал, имеет один и тот же управляющий терминал. Терминал может быть управляющим терминалом не более одного сеанса. Управляющий терминал для сеанса назначается лидером сеанса способом, определяемым реализацией. Если у лидера сеанса нет управляющего терминала, и он открывает файл терминального устройства, который еще не связан с сеансом, без использования опции O_NOCTTY (см. Open ()), то зависит от реализации, станет ли терминал управляющим терминалом сеанса. лидер.
Управляющий терминал наследуется дочерним процессом во время вызова функции fork (). Процесс отказывается от своего управляющего терминала, когда он создает новый сеанс с помощью функции setsid ()
; другие процессы, оставшиеся в старом сеансе, которые использовали этот терминал в качестве своего управляющего терминала, продолжают его использовать.После закрытия последнего файлового дескриптора в системе (независимо от того, находится он в текущем сеансе или нет), связанного с управляющим терминалом, не указано, перестают ли все процессы, которые имели этот терминал в качестве своего управляющего терминала, иметь какой-либо управляющий терминал. Не определено, может ли лидер сеанса повторно получить управляющий терминал после того, как управляющий терминал был освобожден таким образом, и каким образом. Процесс не отказывается от своего управляющего терминала, просто закрывая все свои файловые дескрипторы, связанные с управляющим терминалом, если другие процессы продолжают открывать его.
Там много чего осталось неуказанного - и, честно говоря, я думаю, что это имеет смысл. Хотя терминал является ключевым пользовательским интерфейсом, в некоторых случаях это также и множество других вещей - например, реальное оборудование или даже своего рода принтер - но во многих случаях это практически ничего, например xterm
, который представляет собой просто эмулятор. Здесь сложно уточнить детали - и я не думаю, что это в любом случае будет в интересах Unix, потому что терминалы делают гораздо больше, чем Unix.
В любом случае, POSIX также довольно сомнительна в отношении того, как ps
должен вести себя в отношении ctty.
Есть переключатель -a
:
Отлично. Лидеры сеанса могут быть опущены . Это не очень помогает.
И -t
:
или списка, разделенного запятыми. Идентификаторы терминала должны быть предоставлены в формате , определяемом реализацией . ... это еще одно разочарование. Но в нем говорится следующее о системах XSI:
tty04
) или, если имя файла устройства начинается с tty
, просто идентификатора, следующего за символами tty
(например, 04
) . Это немного лучше, но это не путь. Также в системах XSI есть переключатель -d
:
... что, по крайней мере, ясно. Вы также можете указать переключатель -o
utput со строкой формата tty
, но, как вы заметили, его выходной формат определяется реализацией. Тем не менее, я думаю, что это настолько хорошо, насколько возможно. Я думаю, что после большой работы вышеперечисленные переключатели в сочетании с некоторыми другими утилитами могут дать вам довольно неплохую оценку. Честно говоря, я не знаю, когда и как это у вас сломается - и я не мог представить себе ситуацию, в которой это могло бы произойти. Но я думаю, что если мы добавим fuser
и find
, мы сможем проверить путь.
exec 2<>/dev/null
ctty=$(sh -c 'ps -p "$$" -o tty=' <&2)
sid=$(sh -c 'ps -Ao pid= -o tty=|
grep '"$ctty$"' |
grep -Fv "$(ps -do pid=)"' <&2)
find / -type c -name "*${ctty##*/}*" \
-exec fuser -uv {} \; 2>&1 |
grep ".*$ctty.*${sid%%"$ctty"*}"
Материал / dev / null
должен был показать, что он может работать, когда ни одна из поисковых подоболочек не имеет 0,1,2, подключенных к ctty. В любом случае, это напечатает:
/dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh
Теперь вышеупомянутый полный путь на моей машине, и я полагаю, что это будет для большинства людей в большинстве случаев. Я также могу представить, что это может потерпеть неудачу. Это просто грубая эвристика.
Это могло произойти, вероятно, по многим другим причинам, но если вы работаете в системе, которая позволяет лидеру сеанса передавать все дескрипторы в ctty, но при этом оставаться sid, тогда, как позволяет спецификация, то это определенно не пойдет. помогать. Тем не менее, я думаю, что в большинстве случаев это может дать довольно хорошую оценку.
Конечно, простейшее действие, если у вас есть какие-либо дескрипторы, подключенные к вашему ctty, это просто ...
tty <&2
...или похожие.