How to get the real name of the controlling terminal?2019 Community Moderator ElectionHow to get the current terminal name?Some confused concept: ptmx and ttyHow can one check in one's program if it is a service process that was started by systemd?Invoke a command/script disconnected from the controlling terminal?In which cases is SIGHUP not sent to a job when you log out?Setting custom baud rate on consoleTerminal pty name according to the source IP addressWhat part of TTY subsystem control the active /dev/ttyN (TTY device driver N)?Redirect tty to standardHow does the Terminal and the Shell exchange data?Do the output of command `tty` and the file `/dev/tty` both refer to the controlling terminal of the current bash process?Is controlling terminal a per-process concept?

Do f-stop and exposure time perfectly cancel?

Who deserves to be first and second author? PhD student who collected data, research associate who wrote the paper or supervisor?

What's the "normal" opposite of flautando?

Do items de-spawn in Diablo?

In the late 1940’s to early 1950’s what technology was available that could melt a LOT of ice?

Does "variables should live in the smallest scope as possible" include the case "variables should not exist if possible"?

Finding algorithms of QGIS commands?

Virginia employer terminated employee and wants signing bonus returned

What are actual Tesla M60 models used by AWS?

How do I deal with a powergamer in a game full of beginners in a school club?

Good for you! in Russian

Why does Captain Marvel assume the people on this planet know this?

Why does the negative sign arise in this thermodynamic relation?

PTIJ: wiping amalek’s memory?

infinitive telling the purpose

Should QA ask requirements to developers?

Can you reject a postdoc offer after the PI has paid a large sum for flights/accommodation for your visit?

Leftbar without indentation

Intuition behind counterexample of Euler's sum of powers conjecture

What wound would be of little consequence to a biped but terrible for a quadruped?

Can a bounded number sequence be strictly ascending?

What to do when during a meeting client people start to fight (even physically) with each others?

GPLv2 - licensing for commercial use

How much stiffer are 23c tires over 28c?



How to get the real name of the controlling terminal?



2019 Community Moderator ElectionHow to get the current terminal name?Some confused concept: ptmx and ttyHow can one check in one's program if it is a service process that was started by systemd?Invoke a command/script disconnected from the controlling terminal?In which cases is SIGHUP not sent to a job when you log out?Setting custom baud rate on consoleTerminal pty name according to the source IP addressWhat part of TTY subsystem control the active /dev/ttyN (TTY device driver N)?Redirect tty to standardHow does the Terminal and the Shell exchange data?Do the output of command `tty` and the file `/dev/tty` both refer to the controlling terminal of the current bash process?Is controlling terminal a per-process concept?










10















How can one get the real name of the controlling terminal (if there is one, else an error) as a pathname?



By "real name", I mean not /dev/tty, which cannot be used by other arbitrary processes to refer to the same terminal. I prefer the answer as a simple shell code (like the example below) if possible, otherwise as a C function.



Note that this must work even if the standard input is redirected, so that the tty utility cannot be used: one would get a not a tty error in such a case, since tty just prints the file name of the terminal connected to standard input.



Under Linux, one can use:



echo "/dev/`ps -p $$ -o tty | tail -n 1`"


but this is not portable, as according to POSIX, the format of the terminal name is unspecified.



Concerning C functions, ctermid (NULL) returns /dev/tty, which is useless here.



Note: according to the zsh documentation, one should be able to do



zsh -c 'echo $TTY'


but this currently (version 5.0.7) fails when both the standard input and the standard output are redirected:



$ zsh -c 'echo $TTY > /dev/tty' < /dev/null
/dev/pts/9
$ zsh -c 'echo $TTY > /dev/tty' < /dev/null > /dev/null
/dev/tty









share|improve this question
























  • @mikeserv I think that the ps solution covers most systems (and who doesn't help more than ps), possibly with a bit more code to handle the identifier alone (like "04"). I was wondering if there were an even more portable solution.

    – vinc17
    Feb 28 '15 at 2:19












  • It might have to do with pre-paired sets - the old bsd-style pty pairs as well, maybe. Not all ptys are UNIX 98 types. Anyway, from man xterm: -Sccn This option allows xterm to be used as an i/o channel for an existing program... The option value is a few letters of the name of a pty to use in slave mode, plus the inherited fd number. If the option contains a “/” character, it delimites the pty name from the fd.

    – mikeserv
    Feb 28 '15 at 2:31












  • @mikeserv Note that the solution doesn't work with ps from busybox (which is used by Android, BTW), even under GNU/Linux. What do you mean by "xterm can handle that 04"?

    – vinc17
    Feb 28 '15 at 2:31











  • busybox is not POSIX-conformant. toybox, however, does very well.

    – mikeserv
    Feb 28 '15 at 2:33















10















How can one get the real name of the controlling terminal (if there is one, else an error) as a pathname?



By "real name", I mean not /dev/tty, which cannot be used by other arbitrary processes to refer to the same terminal. I prefer the answer as a simple shell code (like the example below) if possible, otherwise as a C function.



Note that this must work even if the standard input is redirected, so that the tty utility cannot be used: one would get a not a tty error in such a case, since tty just prints the file name of the terminal connected to standard input.



Under Linux, one can use:



echo "/dev/`ps -p $$ -o tty | tail -n 1`"


but this is not portable, as according to POSIX, the format of the terminal name is unspecified.



Concerning C functions, ctermid (NULL) returns /dev/tty, which is useless here.



Note: according to the zsh documentation, one should be able to do



zsh -c 'echo $TTY'


but this currently (version 5.0.7) fails when both the standard input and the standard output are redirected:



$ zsh -c 'echo $TTY > /dev/tty' < /dev/null
/dev/pts/9
$ zsh -c 'echo $TTY > /dev/tty' < /dev/null > /dev/null
/dev/tty









share|improve this question
























  • @mikeserv I think that the ps solution covers most systems (and who doesn't help more than ps), possibly with a bit more code to handle the identifier alone (like "04"). I was wondering if there were an even more portable solution.

    – vinc17
    Feb 28 '15 at 2:19












  • It might have to do with pre-paired sets - the old bsd-style pty pairs as well, maybe. Not all ptys are UNIX 98 types. Anyway, from man xterm: -Sccn This option allows xterm to be used as an i/o channel for an existing program... The option value is a few letters of the name of a pty to use in slave mode, plus the inherited fd number. If the option contains a “/” character, it delimites the pty name from the fd.

    – mikeserv
    Feb 28 '15 at 2:31












  • @mikeserv Note that the solution doesn't work with ps from busybox (which is used by Android, BTW), even under GNU/Linux. What do you mean by "xterm can handle that 04"?

    – vinc17
    Feb 28 '15 at 2:31











  • busybox is not POSIX-conformant. toybox, however, does very well.

    – mikeserv
    Feb 28 '15 at 2:33













10












10








10








How can one get the real name of the controlling terminal (if there is one, else an error) as a pathname?



By "real name", I mean not /dev/tty, which cannot be used by other arbitrary processes to refer to the same terminal. I prefer the answer as a simple shell code (like the example below) if possible, otherwise as a C function.



Note that this must work even if the standard input is redirected, so that the tty utility cannot be used: one would get a not a tty error in such a case, since tty just prints the file name of the terminal connected to standard input.



Under Linux, one can use:



echo "/dev/`ps -p $$ -o tty | tail -n 1`"


but this is not portable, as according to POSIX, the format of the terminal name is unspecified.



Concerning C functions, ctermid (NULL) returns /dev/tty, which is useless here.



Note: according to the zsh documentation, one should be able to do



zsh -c 'echo $TTY'


but this currently (version 5.0.7) fails when both the standard input and the standard output are redirected:



$ zsh -c 'echo $TTY > /dev/tty' < /dev/null
/dev/pts/9
$ zsh -c 'echo $TTY > /dev/tty' < /dev/null > /dev/null
/dev/tty









share|improve this question
















How can one get the real name of the controlling terminal (if there is one, else an error) as a pathname?



By "real name", I mean not /dev/tty, which cannot be used by other arbitrary processes to refer to the same terminal. I prefer the answer as a simple shell code (like the example below) if possible, otherwise as a C function.



Note that this must work even if the standard input is redirected, so that the tty utility cannot be used: one would get a not a tty error in such a case, since tty just prints the file name of the terminal connected to standard input.



Under Linux, one can use:



echo "/dev/`ps -p $$ -o tty | tail -n 1`"


but this is not portable, as according to POSIX, the format of the terminal name is unspecified.



Concerning C functions, ctermid (NULL) returns /dev/tty, which is useless here.



Note: according to the zsh documentation, one should be able to do



zsh -c 'echo $TTY'


but this currently (version 5.0.7) fails when both the standard input and the standard output are redirected:



$ zsh -c 'echo $TTY > /dev/tty' < /dev/null
/dev/pts/9
$ zsh -c 'echo $TTY > /dev/tty' < /dev/null > /dev/null
/dev/tty






shell terminal tty controlling-terminal






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 21 '17 at 8:21









anatoly techtonik

9331025




9331025










asked Feb 28 '15 at 1:53









vinc17vinc17

9,0491736




9,0491736












  • @mikeserv I think that the ps solution covers most systems (and who doesn't help more than ps), possibly with a bit more code to handle the identifier alone (like "04"). I was wondering if there were an even more portable solution.

    – vinc17
    Feb 28 '15 at 2:19












  • It might have to do with pre-paired sets - the old bsd-style pty pairs as well, maybe. Not all ptys are UNIX 98 types. Anyway, from man xterm: -Sccn This option allows xterm to be used as an i/o channel for an existing program... The option value is a few letters of the name of a pty to use in slave mode, plus the inherited fd number. If the option contains a “/” character, it delimites the pty name from the fd.

    – mikeserv
    Feb 28 '15 at 2:31












  • @mikeserv Note that the solution doesn't work with ps from busybox (which is used by Android, BTW), even under GNU/Linux. What do you mean by "xterm can handle that 04"?

    – vinc17
    Feb 28 '15 at 2:31











  • busybox is not POSIX-conformant. toybox, however, does very well.

    – mikeserv
    Feb 28 '15 at 2:33

















  • @mikeserv I think that the ps solution covers most systems (and who doesn't help more than ps), possibly with a bit more code to handle the identifier alone (like "04"). I was wondering if there were an even more portable solution.

    – vinc17
    Feb 28 '15 at 2:19












  • It might have to do with pre-paired sets - the old bsd-style pty pairs as well, maybe. Not all ptys are UNIX 98 types. Anyway, from man xterm: -Sccn This option allows xterm to be used as an i/o channel for an existing program... The option value is a few letters of the name of a pty to use in slave mode, plus the inherited fd number. If the option contains a “/” character, it delimites the pty name from the fd.

    – mikeserv
    Feb 28 '15 at 2:31












  • @mikeserv Note that the solution doesn't work with ps from busybox (which is used by Android, BTW), even under GNU/Linux. What do you mean by "xterm can handle that 04"?

    – vinc17
    Feb 28 '15 at 2:31











  • busybox is not POSIX-conformant. toybox, however, does very well.

    – mikeserv
    Feb 28 '15 at 2:33
















@mikeserv I think that the ps solution covers most systems (and who doesn't help more than ps), possibly with a bit more code to handle the identifier alone (like "04"). I was wondering if there were an even more portable solution.

– vinc17
Feb 28 '15 at 2:19






@mikeserv I think that the ps solution covers most systems (and who doesn't help more than ps), possibly with a bit more code to handle the identifier alone (like "04"). I was wondering if there were an even more portable solution.

– vinc17
Feb 28 '15 at 2:19














It might have to do with pre-paired sets - the old bsd-style pty pairs as well, maybe. Not all ptys are UNIX 98 types. Anyway, from man xterm: -Sccn This option allows xterm to be used as an i/o channel for an existing program... The option value is a few letters of the name of a pty to use in slave mode, plus the inherited fd number. If the option contains a “/” character, it delimites the pty name from the fd.

– mikeserv
Feb 28 '15 at 2:31






It might have to do with pre-paired sets - the old bsd-style pty pairs as well, maybe. Not all ptys are UNIX 98 types. Anyway, from man xterm: -Sccn This option allows xterm to be used as an i/o channel for an existing program... The option value is a few letters of the name of a pty to use in slave mode, plus the inherited fd number. If the option contains a “/” character, it delimites the pty name from the fd.

– mikeserv
Feb 28 '15 at 2:31














@mikeserv Note that the solution doesn't work with ps from busybox (which is used by Android, BTW), even under GNU/Linux. What do you mean by "xterm can handle that 04"?

– vinc17
Feb 28 '15 at 2:31





@mikeserv Note that the solution doesn't work with ps from busybox (which is used by Android, BTW), even under GNU/Linux. What do you mean by "xterm can handle that 04"?

– vinc17
Feb 28 '15 at 2:31













busybox is not POSIX-conformant. toybox, however, does very well.

– mikeserv
Feb 28 '15 at 2:33





busybox is not POSIX-conformant. toybox, however, does very well.

– mikeserv
Feb 28 '15 at 2:33










2 Answers
2






active

oldest

votes


















7














The "controlling terminal" aka. ctty, is distincted from "the terminal a process is interacting with".



Standard way of getting the path of ctty is ctermid(3). Upon calling this,
In freebsd since release 10, an actual path is looked up[1],
while older freebsd and glibc implementations[2] unconditionally returns "/dev/tty"].



ps(1) from the linux procps 3.2.8 package, read the numerical entry in /proc/*/stat[3], and then deduct the pathname partially by guessing[4, 5] due to lack of system support[6].



However if we are not strictly interested in the ctty but any terminal associated with stdio, tty(1) prints the terminal path connected to stdin, which is identical to ttyname(fileno(stdin)) in c, and an alternative is readlink /proc/self/fd/0.




Less important thought regarding the unconditional "/dev/tty" behavior: Specs merely say the string returned by ctermid "when used as a path name, refer to the current controlling terminal", instead of some straightforward "is the path name of the current controlling terminal". It might be interpreted as that "/dev/tty" is not the controlling terminal, but only refer to the controlling terminal if the same process open(3) it. Thus not violating the
"a terminal may be ctty for at most one session" rule[7].



Another consequence is that when I am without any controlling terminal, ctermid does not fail -- such failing is allowed by specs[8] --, so only can I become aware of my ctty'lessness until failing a subsequent open(3), which is okay since specs also say calling open(3) on it is not guarranteed to succeed.






share|improve this answer

























  • This is not more portable than the ps solution I gave in my question, since not all OS have a /proc file system. Note that ps itself uses a readlink on /proc/self/fd/2 (which works even is the standard error is redirected).

    – vinc17
    Feb 28 '15 at 2:14






  • 1





    edited. and ps readlink on /proc/*/fd/2 not to find the ctty, but to seek supplementary information in order to map numeric terminal to path, see link[4] [5].

    – 把友情留在无盐
    Feb 28 '15 at 7:31







  • 1





    Excellent edit. Regarding the ctty; I can't speak for vinc17, but while you can probably always write to somewhere, there's only one file that must remain open to keep your process group alive.

    – mikeserv
    Feb 28 '15 at 9:04






  • 1





    @vinc17 - if you have any file descriptors open on your ctty then you can read them with tty. stderr is probably the best because it's spec'd to be open r/w. So tty <&2.

    – mikeserv
    Feb 28 '15 at 12:20






  • 1





    That a given terminal may be ctty for at most one session does not make glibc non-conforming for its ctermid() always returning "/dev/tty". That name refers always to the controlling terminal of the process accessing it, which varies by session. The terminal is session specific, but the name by which it is accessed does not need to be.

    – PellMel
    Dec 8 '16 at 15:00



















5














The POSIX spec really hedges its bets where the Controlling Terminal is concerned, and which it defines thus:




  • Controlling Terminal
    • The question of which of possibly several special files referring to the terminal is meant is not addressed in POSIX.1. The pathname /dev/tty is a synonym for the controlling terminal associated with a process.


That's in the Definitions list - and that's all there is there. But in General Terminal Interface, some more is said:



  • A terminal may belong to a process as its controlling terminal. Each process of a session that has a controlling terminal has the same controlling terminal. A terminal may be the controlling terminal for at most one session. The controlling terminal for a session is allocated by the session leader in an implementation-defined manner. If a session leader has no controlling terminal, and opens a terminal device file that is not already associated with a session without using the O_NOCTTY option (see open()), it is implementation-defined whether the terminal becomes the controlling terminal of the session leader.


  • The controlling terminal is inherited by a child process during a fork() function call. A process relinquishes its controlling terminal when it creates a new session with the setsid() function; other processes remaining in the old session that had this terminal as their controlling terminal continue to have it. Upon the close of the last file descriptor in the system (whether or not it is in the current session) associated with the controlling terminal, it is unspecified whether all processes that had that terminal as their controlling terminal cease to have any controlling terminal. Whether and how a session leader can reacquire a controlling terminal after the controlling terminal has been relinquished in this fashion is unspecified. A process does not relinquish its controlling terminal simply by closing all of its file descriptors associated with the controlling terminal if other processes continue to have it open.


There's a lot there left unspecified - and honestly I think it makes sense. While the terminal is a key user interface, it's also all kinds of other things in some cases - like actual hardware, or even a kind of printer - but in a lot of cases it's practically nothing at all - like an xterm which is just an emulator. It's hard to get specific there - and I don't think it would be much in the interest of Unix anyway, because terminals do a lot more than Unix.



Anyway, POSIX is also pretty iffy on how ps should behave where the ctty is concerned.



There's the -a switch:



  • Write information for all processes associated with terminals. Implementations may omit session leaders from this list.

Great. Session leaders may be omitted. That's not very helpful.



And -t:



  • Write information for processes associated with terminals given in termlist. The application shall ensure that the termlist is a single argument in the form of a <blank> or comma-separated list. Terminal identifiers shall be given in an implementation-defined format.

...which is another let-down. But it does go on to say this about XSI systems:



  • On XSI-conformant systems, they shall be given in one of two forms: the device's filename (for example, tty04) or, if the device's filename starts with tty, just the identifier following the characters tty (for example, 04 ).

That's a little better, but is not a path. Also on XSI systems there is the -d switch:



  • Write information for all processes, except session leaders.

...which is at least clear. You can specify the -output switch as well with the tty format string, but, as you've noted, its output format is implementation-defined. Still, I think it is as good as it gets. I think that - with a lot of work - the above switches in combination with some other utilities can get you a pretty good ballpark. To be quite honest though, I don't know when/how it breaks for you - and I haven't been able to imagine a situation in which it would. But, I think probably if we add fuser and find we can verify the path.



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"*"


The /dev/null stuff was just to show that it could work when none of the searching subshells had any of 0,1,2 connected to the ctty. Anyway, that prints:



/dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh


Now the above gets the full path on my machine, and I imagine it would for most people in most cases. I can also imagine it could fail. It's just rough heuristics.



This is could fail for many other reasons probably, but if you're on a system which allows the session leader to relinquish all descriptors to the ctty and yet remain the sid then as the spec allows, then this is definitely not going to help. That said, I think this can get a pretty good estimate in most cases.



Of course the easiest thing to do if you have any descriptors connected to your ctty is just...



tty <&2


...or similar.






share|improve this answer
























    Your Answer








    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f187319%2fhow-to-get-the-real-name-of-the-controlling-terminal%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    7














    The "controlling terminal" aka. ctty, is distincted from "the terminal a process is interacting with".



    Standard way of getting the path of ctty is ctermid(3). Upon calling this,
    In freebsd since release 10, an actual path is looked up[1],
    while older freebsd and glibc implementations[2] unconditionally returns "/dev/tty"].



    ps(1) from the linux procps 3.2.8 package, read the numerical entry in /proc/*/stat[3], and then deduct the pathname partially by guessing[4, 5] due to lack of system support[6].



    However if we are not strictly interested in the ctty but any terminal associated with stdio, tty(1) prints the terminal path connected to stdin, which is identical to ttyname(fileno(stdin)) in c, and an alternative is readlink /proc/self/fd/0.




    Less important thought regarding the unconditional "/dev/tty" behavior: Specs merely say the string returned by ctermid "when used as a path name, refer to the current controlling terminal", instead of some straightforward "is the path name of the current controlling terminal". It might be interpreted as that "/dev/tty" is not the controlling terminal, but only refer to the controlling terminal if the same process open(3) it. Thus not violating the
    "a terminal may be ctty for at most one session" rule[7].



    Another consequence is that when I am without any controlling terminal, ctermid does not fail -- such failing is allowed by specs[8] --, so only can I become aware of my ctty'lessness until failing a subsequent open(3), which is okay since specs also say calling open(3) on it is not guarranteed to succeed.






    share|improve this answer

























    • This is not more portable than the ps solution I gave in my question, since not all OS have a /proc file system. Note that ps itself uses a readlink on /proc/self/fd/2 (which works even is the standard error is redirected).

      – vinc17
      Feb 28 '15 at 2:14






    • 1





      edited. and ps readlink on /proc/*/fd/2 not to find the ctty, but to seek supplementary information in order to map numeric terminal to path, see link[4] [5].

      – 把友情留在无盐
      Feb 28 '15 at 7:31







    • 1





      Excellent edit. Regarding the ctty; I can't speak for vinc17, but while you can probably always write to somewhere, there's only one file that must remain open to keep your process group alive.

      – mikeserv
      Feb 28 '15 at 9:04






    • 1





      @vinc17 - if you have any file descriptors open on your ctty then you can read them with tty. stderr is probably the best because it's spec'd to be open r/w. So tty <&2.

      – mikeserv
      Feb 28 '15 at 12:20






    • 1





      That a given terminal may be ctty for at most one session does not make glibc non-conforming for its ctermid() always returning "/dev/tty". That name refers always to the controlling terminal of the process accessing it, which varies by session. The terminal is session specific, but the name by which it is accessed does not need to be.

      – PellMel
      Dec 8 '16 at 15:00
















    7














    The "controlling terminal" aka. ctty, is distincted from "the terminal a process is interacting with".



    Standard way of getting the path of ctty is ctermid(3). Upon calling this,
    In freebsd since release 10, an actual path is looked up[1],
    while older freebsd and glibc implementations[2] unconditionally returns "/dev/tty"].



    ps(1) from the linux procps 3.2.8 package, read the numerical entry in /proc/*/stat[3], and then deduct the pathname partially by guessing[4, 5] due to lack of system support[6].



    However if we are not strictly interested in the ctty but any terminal associated with stdio, tty(1) prints the terminal path connected to stdin, which is identical to ttyname(fileno(stdin)) in c, and an alternative is readlink /proc/self/fd/0.




    Less important thought regarding the unconditional "/dev/tty" behavior: Specs merely say the string returned by ctermid "when used as a path name, refer to the current controlling terminal", instead of some straightforward "is the path name of the current controlling terminal". It might be interpreted as that "/dev/tty" is not the controlling terminal, but only refer to the controlling terminal if the same process open(3) it. Thus not violating the
    "a terminal may be ctty for at most one session" rule[7].



    Another consequence is that when I am without any controlling terminal, ctermid does not fail -- such failing is allowed by specs[8] --, so only can I become aware of my ctty'lessness until failing a subsequent open(3), which is okay since specs also say calling open(3) on it is not guarranteed to succeed.






    share|improve this answer

























    • This is not more portable than the ps solution I gave in my question, since not all OS have a /proc file system. Note that ps itself uses a readlink on /proc/self/fd/2 (which works even is the standard error is redirected).

      – vinc17
      Feb 28 '15 at 2:14






    • 1





      edited. and ps readlink on /proc/*/fd/2 not to find the ctty, but to seek supplementary information in order to map numeric terminal to path, see link[4] [5].

      – 把友情留在无盐
      Feb 28 '15 at 7:31







    • 1





      Excellent edit. Regarding the ctty; I can't speak for vinc17, but while you can probably always write to somewhere, there's only one file that must remain open to keep your process group alive.

      – mikeserv
      Feb 28 '15 at 9:04






    • 1





      @vinc17 - if you have any file descriptors open on your ctty then you can read them with tty. stderr is probably the best because it's spec'd to be open r/w. So tty <&2.

      – mikeserv
      Feb 28 '15 at 12:20






    • 1





      That a given terminal may be ctty for at most one session does not make glibc non-conforming for its ctermid() always returning "/dev/tty". That name refers always to the controlling terminal of the process accessing it, which varies by session. The terminal is session specific, but the name by which it is accessed does not need to be.

      – PellMel
      Dec 8 '16 at 15:00














    7












    7








    7







    The "controlling terminal" aka. ctty, is distincted from "the terminal a process is interacting with".



    Standard way of getting the path of ctty is ctermid(3). Upon calling this,
    In freebsd since release 10, an actual path is looked up[1],
    while older freebsd and glibc implementations[2] unconditionally returns "/dev/tty"].



    ps(1) from the linux procps 3.2.8 package, read the numerical entry in /proc/*/stat[3], and then deduct the pathname partially by guessing[4, 5] due to lack of system support[6].



    However if we are not strictly interested in the ctty but any terminal associated with stdio, tty(1) prints the terminal path connected to stdin, which is identical to ttyname(fileno(stdin)) in c, and an alternative is readlink /proc/self/fd/0.




    Less important thought regarding the unconditional "/dev/tty" behavior: Specs merely say the string returned by ctermid "when used as a path name, refer to the current controlling terminal", instead of some straightforward "is the path name of the current controlling terminal". It might be interpreted as that "/dev/tty" is not the controlling terminal, but only refer to the controlling terminal if the same process open(3) it. Thus not violating the
    "a terminal may be ctty for at most one session" rule[7].



    Another consequence is that when I am without any controlling terminal, ctermid does not fail -- such failing is allowed by specs[8] --, so only can I become aware of my ctty'lessness until failing a subsequent open(3), which is okay since specs also say calling open(3) on it is not guarranteed to succeed.






    share|improve this answer















    The "controlling terminal" aka. ctty, is distincted from "the terminal a process is interacting with".



    Standard way of getting the path of ctty is ctermid(3). Upon calling this,
    In freebsd since release 10, an actual path is looked up[1],
    while older freebsd and glibc implementations[2] unconditionally returns "/dev/tty"].



    ps(1) from the linux procps 3.2.8 package, read the numerical entry in /proc/*/stat[3], and then deduct the pathname partially by guessing[4, 5] due to lack of system support[6].



    However if we are not strictly interested in the ctty but any terminal associated with stdio, tty(1) prints the terminal path connected to stdin, which is identical to ttyname(fileno(stdin)) in c, and an alternative is readlink /proc/self/fd/0.




    Less important thought regarding the unconditional "/dev/tty" behavior: Specs merely say the string returned by ctermid "when used as a path name, refer to the current controlling terminal", instead of some straightforward "is the path name of the current controlling terminal". It might be interpreted as that "/dev/tty" is not the controlling terminal, but only refer to the controlling terminal if the same process open(3) it. Thus not violating the
    "a terminal may be ctty for at most one session" rule[7].



    Another consequence is that when I am without any controlling terminal, ctermid does not fail -- such failing is allowed by specs[8] --, so only can I become aware of my ctty'lessness until failing a subsequent open(3), which is okay since specs also say calling open(3) on it is not guarranteed to succeed.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 1 hour ago

























    answered Feb 28 '15 at 2:10









    把友情留在无盐把友情留在无盐

    530310




    530310












    • This is not more portable than the ps solution I gave in my question, since not all OS have a /proc file system. Note that ps itself uses a readlink on /proc/self/fd/2 (which works even is the standard error is redirected).

      – vinc17
      Feb 28 '15 at 2:14






    • 1





      edited. and ps readlink on /proc/*/fd/2 not to find the ctty, but to seek supplementary information in order to map numeric terminal to path, see link[4] [5].

      – 把友情留在无盐
      Feb 28 '15 at 7:31







    • 1





      Excellent edit. Regarding the ctty; I can't speak for vinc17, but while you can probably always write to somewhere, there's only one file that must remain open to keep your process group alive.

      – mikeserv
      Feb 28 '15 at 9:04






    • 1





      @vinc17 - if you have any file descriptors open on your ctty then you can read them with tty. stderr is probably the best because it's spec'd to be open r/w. So tty <&2.

      – mikeserv
      Feb 28 '15 at 12:20






    • 1





      That a given terminal may be ctty for at most one session does not make glibc non-conforming for its ctermid() always returning "/dev/tty". That name refers always to the controlling terminal of the process accessing it, which varies by session. The terminal is session specific, but the name by which it is accessed does not need to be.

      – PellMel
      Dec 8 '16 at 15:00


















    • This is not more portable than the ps solution I gave in my question, since not all OS have a /proc file system. Note that ps itself uses a readlink on /proc/self/fd/2 (which works even is the standard error is redirected).

      – vinc17
      Feb 28 '15 at 2:14






    • 1





      edited. and ps readlink on /proc/*/fd/2 not to find the ctty, but to seek supplementary information in order to map numeric terminal to path, see link[4] [5].

      – 把友情留在无盐
      Feb 28 '15 at 7:31







    • 1





      Excellent edit. Regarding the ctty; I can't speak for vinc17, but while you can probably always write to somewhere, there's only one file that must remain open to keep your process group alive.

      – mikeserv
      Feb 28 '15 at 9:04






    • 1





      @vinc17 - if you have any file descriptors open on your ctty then you can read them with tty. stderr is probably the best because it's spec'd to be open r/w. So tty <&2.

      – mikeserv
      Feb 28 '15 at 12:20






    • 1





      That a given terminal may be ctty for at most one session does not make glibc non-conforming for its ctermid() always returning "/dev/tty". That name refers always to the controlling terminal of the process accessing it, which varies by session. The terminal is session specific, but the name by which it is accessed does not need to be.

      – PellMel
      Dec 8 '16 at 15:00

















    This is not more portable than the ps solution I gave in my question, since not all OS have a /proc file system. Note that ps itself uses a readlink on /proc/self/fd/2 (which works even is the standard error is redirected).

    – vinc17
    Feb 28 '15 at 2:14





    This is not more portable than the ps solution I gave in my question, since not all OS have a /proc file system. Note that ps itself uses a readlink on /proc/self/fd/2 (which works even is the standard error is redirected).

    – vinc17
    Feb 28 '15 at 2:14




    1




    1





    edited. and ps readlink on /proc/*/fd/2 not to find the ctty, but to seek supplementary information in order to map numeric terminal to path, see link[4] [5].

    – 把友情留在无盐
    Feb 28 '15 at 7:31






    edited. and ps readlink on /proc/*/fd/2 not to find the ctty, but to seek supplementary information in order to map numeric terminal to path, see link[4] [5].

    – 把友情留在无盐
    Feb 28 '15 at 7:31





    1




    1





    Excellent edit. Regarding the ctty; I can't speak for vinc17, but while you can probably always write to somewhere, there's only one file that must remain open to keep your process group alive.

    – mikeserv
    Feb 28 '15 at 9:04





    Excellent edit. Regarding the ctty; I can't speak for vinc17, but while you can probably always write to somewhere, there's only one file that must remain open to keep your process group alive.

    – mikeserv
    Feb 28 '15 at 9:04




    1




    1





    @vinc17 - if you have any file descriptors open on your ctty then you can read them with tty. stderr is probably the best because it's spec'd to be open r/w. So tty <&2.

    – mikeserv
    Feb 28 '15 at 12:20





    @vinc17 - if you have any file descriptors open on your ctty then you can read them with tty. stderr is probably the best because it's spec'd to be open r/w. So tty <&2.

    – mikeserv
    Feb 28 '15 at 12:20




    1




    1





    That a given terminal may be ctty for at most one session does not make glibc non-conforming for its ctermid() always returning "/dev/tty". That name refers always to the controlling terminal of the process accessing it, which varies by session. The terminal is session specific, but the name by which it is accessed does not need to be.

    – PellMel
    Dec 8 '16 at 15:00






    That a given terminal may be ctty for at most one session does not make glibc non-conforming for its ctermid() always returning "/dev/tty". That name refers always to the controlling terminal of the process accessing it, which varies by session. The terminal is session specific, but the name by which it is accessed does not need to be.

    – PellMel
    Dec 8 '16 at 15:00














    5














    The POSIX spec really hedges its bets where the Controlling Terminal is concerned, and which it defines thus:




    • Controlling Terminal
      • The question of which of possibly several special files referring to the terminal is meant is not addressed in POSIX.1. The pathname /dev/tty is a synonym for the controlling terminal associated with a process.


    That's in the Definitions list - and that's all there is there. But in General Terminal Interface, some more is said:



    • A terminal may belong to a process as its controlling terminal. Each process of a session that has a controlling terminal has the same controlling terminal. A terminal may be the controlling terminal for at most one session. The controlling terminal for a session is allocated by the session leader in an implementation-defined manner. If a session leader has no controlling terminal, and opens a terminal device file that is not already associated with a session without using the O_NOCTTY option (see open()), it is implementation-defined whether the terminal becomes the controlling terminal of the session leader.


    • The controlling terminal is inherited by a child process during a fork() function call. A process relinquishes its controlling terminal when it creates a new session with the setsid() function; other processes remaining in the old session that had this terminal as their controlling terminal continue to have it. Upon the close of the last file descriptor in the system (whether or not it is in the current session) associated with the controlling terminal, it is unspecified whether all processes that had that terminal as their controlling terminal cease to have any controlling terminal. Whether and how a session leader can reacquire a controlling terminal after the controlling terminal has been relinquished in this fashion is unspecified. A process does not relinquish its controlling terminal simply by closing all of its file descriptors associated with the controlling terminal if other processes continue to have it open.


    There's a lot there left unspecified - and honestly I think it makes sense. While the terminal is a key user interface, it's also all kinds of other things in some cases - like actual hardware, or even a kind of printer - but in a lot of cases it's practically nothing at all - like an xterm which is just an emulator. It's hard to get specific there - and I don't think it would be much in the interest of Unix anyway, because terminals do a lot more than Unix.



    Anyway, POSIX is also pretty iffy on how ps should behave where the ctty is concerned.



    There's the -a switch:



    • Write information for all processes associated with terminals. Implementations may omit session leaders from this list.

    Great. Session leaders may be omitted. That's not very helpful.



    And -t:



    • Write information for processes associated with terminals given in termlist. The application shall ensure that the termlist is a single argument in the form of a <blank> or comma-separated list. Terminal identifiers shall be given in an implementation-defined format.

    ...which is another let-down. But it does go on to say this about XSI systems:



    • On XSI-conformant systems, they shall be given in one of two forms: the device's filename (for example, tty04) or, if the device's filename starts with tty, just the identifier following the characters tty (for example, 04 ).

    That's a little better, but is not a path. Also on XSI systems there is the -d switch:



    • Write information for all processes, except session leaders.

    ...which is at least clear. You can specify the -output switch as well with the tty format string, but, as you've noted, its output format is implementation-defined. Still, I think it is as good as it gets. I think that - with a lot of work - the above switches in combination with some other utilities can get you a pretty good ballpark. To be quite honest though, I don't know when/how it breaks for you - and I haven't been able to imagine a situation in which it would. But, I think probably if we add fuser and find we can verify the path.



    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"*"


    The /dev/null stuff was just to show that it could work when none of the searching subshells had any of 0,1,2 connected to the ctty. Anyway, that prints:



    /dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh


    Now the above gets the full path on my machine, and I imagine it would for most people in most cases. I can also imagine it could fail. It's just rough heuristics.



    This is could fail for many other reasons probably, but if you're on a system which allows the session leader to relinquish all descriptors to the ctty and yet remain the sid then as the spec allows, then this is definitely not going to help. That said, I think this can get a pretty good estimate in most cases.



    Of course the easiest thing to do if you have any descriptors connected to your ctty is just...



    tty <&2


    ...or similar.






    share|improve this answer





























      5














      The POSIX spec really hedges its bets where the Controlling Terminal is concerned, and which it defines thus:




      • Controlling Terminal
        • The question of which of possibly several special files referring to the terminal is meant is not addressed in POSIX.1. The pathname /dev/tty is a synonym for the controlling terminal associated with a process.


      That's in the Definitions list - and that's all there is there. But in General Terminal Interface, some more is said:



      • A terminal may belong to a process as its controlling terminal. Each process of a session that has a controlling terminal has the same controlling terminal. A terminal may be the controlling terminal for at most one session. The controlling terminal for a session is allocated by the session leader in an implementation-defined manner. If a session leader has no controlling terminal, and opens a terminal device file that is not already associated with a session without using the O_NOCTTY option (see open()), it is implementation-defined whether the terminal becomes the controlling terminal of the session leader.


      • The controlling terminal is inherited by a child process during a fork() function call. A process relinquishes its controlling terminal when it creates a new session with the setsid() function; other processes remaining in the old session that had this terminal as their controlling terminal continue to have it. Upon the close of the last file descriptor in the system (whether or not it is in the current session) associated with the controlling terminal, it is unspecified whether all processes that had that terminal as their controlling terminal cease to have any controlling terminal. Whether and how a session leader can reacquire a controlling terminal after the controlling terminal has been relinquished in this fashion is unspecified. A process does not relinquish its controlling terminal simply by closing all of its file descriptors associated with the controlling terminal if other processes continue to have it open.


      There's a lot there left unspecified - and honestly I think it makes sense. While the terminal is a key user interface, it's also all kinds of other things in some cases - like actual hardware, or even a kind of printer - but in a lot of cases it's practically nothing at all - like an xterm which is just an emulator. It's hard to get specific there - and I don't think it would be much in the interest of Unix anyway, because terminals do a lot more than Unix.



      Anyway, POSIX is also pretty iffy on how ps should behave where the ctty is concerned.



      There's the -a switch:



      • Write information for all processes associated with terminals. Implementations may omit session leaders from this list.

      Great. Session leaders may be omitted. That's not very helpful.



      And -t:



      • Write information for processes associated with terminals given in termlist. The application shall ensure that the termlist is a single argument in the form of a <blank> or comma-separated list. Terminal identifiers shall be given in an implementation-defined format.

      ...which is another let-down. But it does go on to say this about XSI systems:



      • On XSI-conformant systems, they shall be given in one of two forms: the device's filename (for example, tty04) or, if the device's filename starts with tty, just the identifier following the characters tty (for example, 04 ).

      That's a little better, but is not a path. Also on XSI systems there is the -d switch:



      • Write information for all processes, except session leaders.

      ...which is at least clear. You can specify the -output switch as well with the tty format string, but, as you've noted, its output format is implementation-defined. Still, I think it is as good as it gets. I think that - with a lot of work - the above switches in combination with some other utilities can get you a pretty good ballpark. To be quite honest though, I don't know when/how it breaks for you - and I haven't been able to imagine a situation in which it would. But, I think probably if we add fuser and find we can verify the path.



      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"*"


      The /dev/null stuff was just to show that it could work when none of the searching subshells had any of 0,1,2 connected to the ctty. Anyway, that prints:



      /dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh


      Now the above gets the full path on my machine, and I imagine it would for most people in most cases. I can also imagine it could fail. It's just rough heuristics.



      This is could fail for many other reasons probably, but if you're on a system which allows the session leader to relinquish all descriptors to the ctty and yet remain the sid then as the spec allows, then this is definitely not going to help. That said, I think this can get a pretty good estimate in most cases.



      Of course the easiest thing to do if you have any descriptors connected to your ctty is just...



      tty <&2


      ...or similar.






      share|improve this answer



























        5












        5








        5







        The POSIX spec really hedges its bets where the Controlling Terminal is concerned, and which it defines thus:




        • Controlling Terminal
          • The question of which of possibly several special files referring to the terminal is meant is not addressed in POSIX.1. The pathname /dev/tty is a synonym for the controlling terminal associated with a process.


        That's in the Definitions list - and that's all there is there. But in General Terminal Interface, some more is said:



        • A terminal may belong to a process as its controlling terminal. Each process of a session that has a controlling terminal has the same controlling terminal. A terminal may be the controlling terminal for at most one session. The controlling terminal for a session is allocated by the session leader in an implementation-defined manner. If a session leader has no controlling terminal, and opens a terminal device file that is not already associated with a session without using the O_NOCTTY option (see open()), it is implementation-defined whether the terminal becomes the controlling terminal of the session leader.


        • The controlling terminal is inherited by a child process during a fork() function call. A process relinquishes its controlling terminal when it creates a new session with the setsid() function; other processes remaining in the old session that had this terminal as their controlling terminal continue to have it. Upon the close of the last file descriptor in the system (whether or not it is in the current session) associated with the controlling terminal, it is unspecified whether all processes that had that terminal as their controlling terminal cease to have any controlling terminal. Whether and how a session leader can reacquire a controlling terminal after the controlling terminal has been relinquished in this fashion is unspecified. A process does not relinquish its controlling terminal simply by closing all of its file descriptors associated with the controlling terminal if other processes continue to have it open.


        There's a lot there left unspecified - and honestly I think it makes sense. While the terminal is a key user interface, it's also all kinds of other things in some cases - like actual hardware, or even a kind of printer - but in a lot of cases it's practically nothing at all - like an xterm which is just an emulator. It's hard to get specific there - and I don't think it would be much in the interest of Unix anyway, because terminals do a lot more than Unix.



        Anyway, POSIX is also pretty iffy on how ps should behave where the ctty is concerned.



        There's the -a switch:



        • Write information for all processes associated with terminals. Implementations may omit session leaders from this list.

        Great. Session leaders may be omitted. That's not very helpful.



        And -t:



        • Write information for processes associated with terminals given in termlist. The application shall ensure that the termlist is a single argument in the form of a <blank> or comma-separated list. Terminal identifiers shall be given in an implementation-defined format.

        ...which is another let-down. But it does go on to say this about XSI systems:



        • On XSI-conformant systems, they shall be given in one of two forms: the device's filename (for example, tty04) or, if the device's filename starts with tty, just the identifier following the characters tty (for example, 04 ).

        That's a little better, but is not a path. Also on XSI systems there is the -d switch:



        • Write information for all processes, except session leaders.

        ...which is at least clear. You can specify the -output switch as well with the tty format string, but, as you've noted, its output format is implementation-defined. Still, I think it is as good as it gets. I think that - with a lot of work - the above switches in combination with some other utilities can get you a pretty good ballpark. To be quite honest though, I don't know when/how it breaks for you - and I haven't been able to imagine a situation in which it would. But, I think probably if we add fuser and find we can verify the path.



        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"*"


        The /dev/null stuff was just to show that it could work when none of the searching subshells had any of 0,1,2 connected to the ctty. Anyway, that prints:



        /dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh


        Now the above gets the full path on my machine, and I imagine it would for most people in most cases. I can also imagine it could fail. It's just rough heuristics.



        This is could fail for many other reasons probably, but if you're on a system which allows the session leader to relinquish all descriptors to the ctty and yet remain the sid then as the spec allows, then this is definitely not going to help. That said, I think this can get a pretty good estimate in most cases.



        Of course the easiest thing to do if you have any descriptors connected to your ctty is just...



        tty <&2


        ...or similar.






        share|improve this answer















        The POSIX spec really hedges its bets where the Controlling Terminal is concerned, and which it defines thus:




        • Controlling Terminal
          • The question of which of possibly several special files referring to the terminal is meant is not addressed in POSIX.1. The pathname /dev/tty is a synonym for the controlling terminal associated with a process.


        That's in the Definitions list - and that's all there is there. But in General Terminal Interface, some more is said:



        • A terminal may belong to a process as its controlling terminal. Each process of a session that has a controlling terminal has the same controlling terminal. A terminal may be the controlling terminal for at most one session. The controlling terminal for a session is allocated by the session leader in an implementation-defined manner. If a session leader has no controlling terminal, and opens a terminal device file that is not already associated with a session without using the O_NOCTTY option (see open()), it is implementation-defined whether the terminal becomes the controlling terminal of the session leader.


        • The controlling terminal is inherited by a child process during a fork() function call. A process relinquishes its controlling terminal when it creates a new session with the setsid() function; other processes remaining in the old session that had this terminal as their controlling terminal continue to have it. Upon the close of the last file descriptor in the system (whether or not it is in the current session) associated with the controlling terminal, it is unspecified whether all processes that had that terminal as their controlling terminal cease to have any controlling terminal. Whether and how a session leader can reacquire a controlling terminal after the controlling terminal has been relinquished in this fashion is unspecified. A process does not relinquish its controlling terminal simply by closing all of its file descriptors associated with the controlling terminal if other processes continue to have it open.


        There's a lot there left unspecified - and honestly I think it makes sense. While the terminal is a key user interface, it's also all kinds of other things in some cases - like actual hardware, or even a kind of printer - but in a lot of cases it's practically nothing at all - like an xterm which is just an emulator. It's hard to get specific there - and I don't think it would be much in the interest of Unix anyway, because terminals do a lot more than Unix.



        Anyway, POSIX is also pretty iffy on how ps should behave where the ctty is concerned.



        There's the -a switch:



        • Write information for all processes associated with terminals. Implementations may omit session leaders from this list.

        Great. Session leaders may be omitted. That's not very helpful.



        And -t:



        • Write information for processes associated with terminals given in termlist. The application shall ensure that the termlist is a single argument in the form of a <blank> or comma-separated list. Terminal identifiers shall be given in an implementation-defined format.

        ...which is another let-down. But it does go on to say this about XSI systems:



        • On XSI-conformant systems, they shall be given in one of two forms: the device's filename (for example, tty04) or, if the device's filename starts with tty, just the identifier following the characters tty (for example, 04 ).

        That's a little better, but is not a path. Also on XSI systems there is the -d switch:



        • Write information for all processes, except session leaders.

        ...which is at least clear. You can specify the -output switch as well with the tty format string, but, as you've noted, its output format is implementation-defined. Still, I think it is as good as it gets. I think that - with a lot of work - the above switches in combination with some other utilities can get you a pretty good ballpark. To be quite honest though, I don't know when/how it breaks for you - and I haven't been able to imagine a situation in which it would. But, I think probably if we add fuser and find we can verify the path.



        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"*"


        The /dev/null stuff was just to show that it could work when none of the searching subshells had any of 0,1,2 connected to the ctty. Anyway, that prints:



        /dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh


        Now the above gets the full path on my machine, and I imagine it would for most people in most cases. I can also imagine it could fail. It's just rough heuristics.



        This is could fail for many other reasons probably, but if you're on a system which allows the session leader to relinquish all descriptors to the ctty and yet remain the sid then as the spec allows, then this is definitely not going to help. That said, I think this can get a pretty good estimate in most cases.



        Of course the easiest thing to do if you have any descriptors connected to your ctty is just...



        tty <&2


        ...or similar.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 28 '15 at 14:29

























        answered Feb 28 '15 at 14:23









        mikeservmikeserv

        45.9k668160




        45.9k668160



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f187319%2fhow-to-get-the-real-name-of-the-controlling-terminal%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            -controlling-terminal, shell, terminal, tty

            Popular posts from this blog

            Frič See also Navigation menuinternal link

            Identify plant with long narrow paired leaves and reddish stems Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?What is this plant with long sharp leaves? Is it a weed?What is this 3ft high, stalky plant, with mid sized narrow leaves?What is this young shrub with opposite ovate, crenate leaves and reddish stems?What is this plant with large broad serrated leaves?Identify this upright branching weed with long leaves and reddish stemsPlease help me identify this bulbous plant with long, broad leaves and white flowersWhat is this small annual with narrow gray/green leaves and rust colored daisy-type flowers?What is this chilli plant?Does anyone know what type of chilli plant this is?Help identify this plant

            fontconfig warning: “/etc/fonts/fonts.conf”, line 100: unknown “element blank” The 2019 Stack Overflow Developer Survey Results Are In“tar: unrecognized option --warning” during 'apt-get install'How to fix Fontconfig errorHow do I figure out which font file is chosen for a system generic font alias?Why are some apt-get-installed fonts being ignored by fc-list, xfontsel, etc?Reload settings in /etc/fonts/conf.dTaking 30 seconds longer to boot after upgrade from jessie to stretchHow to match multiple font names with a single <match> element?Adding a custom font to fontconfigRemoving fonts from fontconfig <match> resultsBroken fonts after upgrading Firefox ESR to latest Firefox