View RSS Feed

Hibernate

Linux terminal magick, part 1

Rate this Entry
by , 08-12-2011 at 02:15 AM (1878 Views)
Are you a hardcore GNU/Linux user like me?
Then you are probably sick of Java (natively) not letting you print in the terminal with colours.
In a series of Web logs, I will describe how to, in GNU/Linux, print in the terminal with colours and other stuff.
Keep in mind that you need a TTY (e.g. gnome-terminal, xterm, Linux VT (linux)), Eclipse's built in console will not do.

We will begin with letting Java accept ^C and ^\ (also know as ^4) from the terminal.

First we note that if we start a process from Java it will not share tty with your program, so running "echo `tty`" will tell you that you are using a tty, even if your programming is using a tty.
Linux have a character device symbolic link file named /dev/stdout, it is your tty. Printing to it will print to your terminal.
Since it is a symbolic link we must get it target, its canonical path:
tty = (new File("/dev/stdout")).getCanonicalPath();
You can store tty where it suits you, it will not be modified.

So in our class TerminalMagick we write (for clarity we will not use $NON-NLS comments, as used in Eclipse):

Java Code:
import java.io.*;

public class TerminalMagick
{
    /**
     * The stdout tty. This code assumes you have same stdin tty as stdout tty.
     */
    protected static String tty;

    /**
     * Class initialiser
     */
    static
    {
        //It is imported to use canonical path and not absolute path, otherwise it will change inode
        TerminalMagick.tty = (new File("/dev/stdout")).getCanonicalPath();
    }
}
GNU have a nice program called stty, it will let you set various flags for your tty.
On of those flags is isig, that lets you specify whether interruption signals should be send
from the terminal when you press for example ^C.
To tell stty to use your terminal we start it with: < TerminalMagick.tty

Java Code:
import java.io.*;

public class TerminalMagick
{
    // [⋅⋅⋅], the old stuff

    /**
     * Sets the the value of the ISIG flag; iff on signals may be cued from the TTY when the user presses special key combinations,
     * like ^C and ^\ (also know as ^4). The to 'false' to allow ^C (otherwise abort signal) and ^\(otherwise process dump (should actually be quit) signal).
     *
     * @param   on           Whether the flag should be on.
     * @throws  IOException  Should not be thrown in GNU.
     */
    public static void setInterruptionSignalFlag(final boolean on) throws IOException
    {
        (new ProcessBuilder("/bin/sh", "-c", "stty " + (on ? "isig" : "-isig") + " < " + TerminalMagick.tty + " > /dev/null")).start();
    }
}

Now, to let you use ^C and ^\ in your terminal (this will usable later, in another post) you can to this in your main method:

Java Code:
public static void main(final String... args)
{
    try
    {
        TerminalMagick.setInterruptionSignalFlag(false); //Lets you use ^C and ^\.

        //Do your normal stuff here…
    }
    finally //Runs when the try (and its catches) is complete, even if the method have returned
    {
        TerminalMagick.setInterruptionSignalFlag(true); //Resets ^C and ^\ to send signals (abort and quit).
    }
}

Stay tuned for [in the next part] password fields in the terminal (no echoing) and unbuffered input (each character send when typed, not on Enter)...

Submit "Linux terminal magick, part 1" to Facebook Submit "Linux terminal magick, part 1" to Digg Submit "Linux terminal magick, part 1" to del.icio.us Submit "Linux terminal magick, part 1" to StumbleUpon Submit "Linux terminal magick, part 1" to Google

Updated 08-12-2011 at 06:42 AM by Hibernate

Tags: None Add / Edit Tags
Categories
Terminal cues , Linux

Comments