If you open a terminal and type tty you’ll get something like this,

$ tty

The return of tty depends on your OS but it’ll be some file like object. If you split your terminal screen (or open a new one) and run the tty command again you’ll see a different file being returned.


$ tty

If I stay in this second terminal and run this command

echo "Hello world" > /dev/ttys016

and go back to my first terminal, I’ll find that it has the text “Hello world” in it. That’s pretty cool.

What is going on here? Well it turns out that the *nix terminals use file like objects to interact with data in and out.

If I run ls on the tty file I get,

$ ls -l /dev/ttys017
crw--w----  1 ahmad  tty   16,  14 Apr 26 13:56 /dev/ttys016

But.. wait, what kind of file is that? This SO Answers explains it well,

The ‘c’ means it’s a character device. tty is a special file representing the ‘controlling terminal’ for the current process.

Character Devices

Unix supports ‘device files’, which aren’t really files at all, but file-like access points to hardware devices. A ‘character’ device is one which is interfaced byte-by-byte (as opposed to buffered IO).


/dev/tty is a special file, representing the terminal for the current process. So, when you echo 1 > /dev/tty, your message (‘1’) will appear on your screen. Likewise, when you cat /dev/tty, your subsequent input gets duplicated (until you press Ctrl-C).

/dev/tty doesn’t ‘contain’ anything as such, but you can read from it and write to it (for what it’s worth). I can’t think of a good use for it, but there are similar files which are very useful for simple IO operations (e.g. /dev/ttyS0 is normally your serial port)

This quote is from :

“/dev/tty stands for the controlling terminal (if any) for the current process. To find out which tty’s are attached to which processes use the “ps -a” command at the shell prompt (command line). Look at the “tty” column. For the shell process you’re in, /dev/tty is the terminal you are now using. Type “tty” at the shell prompt to see what it is (see manual pg. tty(1)). /dev/tty is something like a link to the actually terminal device name with some additional features for C-programmers: see the manual page tty(4).”

Here is the man page:

Unix Exit Codes & Chaining CLI Commands

In linux you can execute 2 commands in your terminal by either using a ; or && between commands.


$ echo "Hello" && echo "World"



$ echo "Hello"; echo "World"


But the semicolon and double ampersands are not synonymous. If you use a semicolon you’re saying ‘execute all these commands, who cares if one of them fails’. But when you use double ampersands you’re saying ‘execute all these commands but only if the previous one succeeds’. How do you know if the previous command succeeded? Use the exit codes.

I remember when where writing C/C++ code in undergrad we always ended the main function with return 0. In python you’d tell a program to finish by writing exit(0). But the C/Python programs would work if you returned/exited with 1 instead of 0. However, in the unix world, returning 0 meant the program succeeded but returning 1 meant failure. Here’s a simple python script to test this,

import sys

if __name__ == '__main__':
    exit_code = int(sys.argv[1])
    print('Exiting w/code: {}'.format(exit_code))

Now I can test out exiting a program with 0/1 and ;/&&.

Exiting with 0
$ python 0 && echo 'Hello World'

Exiting w/code: 0
Hello World
$ python 1; echo 'Hello World'

Exiting w/code: 0
Hello World
Exiting with 1
$ python 1 && echo 'Hello World'

Exiting w/code: 1
Hello World
$ python 1; echo 'Hello World'

Exiting w/code: 1

You can find more on exit codes here and here

The curiosity to look into tty came from talk by MJD and the curiousity to look into exit codes came from pairing with Aditya