javamacosterminal

`tput cols` always returns default 80


I made a library years ago to render in the terminal. When running it again in 2025 it is partly broken.

Here is a small example that isolates the problem:

TerminalCols.java

package p5_terminal_graphics_examples;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class TerminalCols {
    
    public static void main(String[] args) {
        while (true) {
            int cols = cols();
            System.out.println("Terminal columns: " + cols);
            
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static public int cols() {
        return Integer.parseInt(cmd("tput cols"));
    }

    static public String cmd(String args) {
        return exec("sh", "-c", args);
    }

    static public String exec(String... cmd) {

        try {
            ByteArrayOutputStream bout = new ByteArrayOutputStream();

            Process p;
            
            p = Runtime.getRuntime().exec(cmd);
            
            int c;
            InputStream in = p.getInputStream();

            while ((c = in.read()) != -1) {
                bout.write(c);
            }

            in = p.getErrorStream();

            while ((c = in.read()) != -1) {
                bout.write(c);
            }

            p.waitFor();

            String result = new String(bout.toByteArray());
            return result.trim();
        } 
        catch (IOException | InterruptedException e) {
            return null;
        }
        
    }
}

The code above should print out the amount of columns the terminal has every second. However it prints always the default 80.

If I type directly tput cols in the terminal then it always returns the correct answer.

So over time something broke and I don't know how to continue to figure out how to fix this. Any help would be welcome.


Solution

  • tput has to have access to terminal in order to get terminal properties.

    Try :

    return Integer.parseInt(cmd("tput cols 2>/dev/tty"));