LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-13-2003, 05:01 AM   #1
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Rep: Reputation: 30
Scripting question: the width of the terminal window


Hello,

I'm using a lot of scripts to automatize stuff, and when I echo something I usually pipe it through fold to get a nice length on the lines - for instance

echo "blah blah" | fold -s -w 80

Now, I'd like to adapt the line length to the actual width of the terminal window - does anyone know how to do this? I mean, so that I could do something like

echo "blah blah" | fold -s -w `command to get the terminal width`

It would look much nicer

Any help is much appreciated!

Stefan
 
Old 08-13-2003, 05:45 AM   #2
kev82
Senior Member
 
Registered: Apr 2003
Location: Lancaster, England
Distribution: Debian Etch, OS X 10.4
Posts: 1,263

Rep: Reputation: 50
<edit> ignore what i posted before, bash sets the terminal size in two variables, $LINES and $COLUMNS

Last edited by kev82; 08-13-2003 at 05:55 AM.
 
Old 08-14-2003, 04:36 AM   #3
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Original Poster
Rep: Reputation: 30
Thanks! But this is odd... I can echo the variables from the command line and get the proper results, but in my script(s) the $LINES and $COLUMNS are empty... This quick and silly test gives nothing for me:

Code:
#!/bin/bash

echo $COLUMNS
echo $LINES
Any ideas?
 
Old 08-14-2003, 09:23 AM   #4
kev82
Senior Member
 
Registered: Apr 2003
Location: Lancaster, England
Distribution: Debian Etch, OS X 10.4
Posts: 1,263

Rep: Reputation: 50
im afraid that bash isnt really my area of expertise, however, the following badly written c program will get the terminal width and height, feel free to tidy it up.
Code:
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>

int main()
{
    struct winsize ws;

    ioctl(STDIN_FILENO, TIOCGWINSZ, &ws);
    printf("%d\n%d\n", ws.ws_col, ws.ws_row);
    return 0;
}
changes that should be made - it could use error checking, some options for output, and replace stdin_fileno with a terminal device from command line.

Last edited by kev82; 08-14-2003 at 09:24 AM.
 
Old 08-14-2003, 10:14 AM   #5
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Original Poster
Rep: Reputation: 30
Heh, my area of expertise certainly isn't C But thanks a bunch for your help, I'll see if I can get something out of it.
 
Old 08-14-2003, 03:04 PM   #6
devoyage
Member
 
Registered: Aug 2003
Distribution: many
Posts: 37

Rep: Reputation: 15
Check out the 'stty' function...

Code:
$ stty -a
speed 38400 baud; 24 rows; 80 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
        -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
        -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff -ixany -imaxbel -ignbrk
        -brkint -inpck -ignpar -parmrk
oflags: opost onlcr -ocrnl -oxtabs -onocr -onlret
cflags: cread cs8 parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
        -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
        eol2 = <undef>; erase = ^H; erase2 = ^@; intr = ^C; kill = ^U;
        lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q;
        status = <undef>; stop = ^S; susp = ^Z; time = 0; werase = ^W;
 
Old 08-15-2003, 06:25 AM   #7
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Original Poster
Rep: Reputation: 30
Aha! This seems to be something I can use directly in a script - thanks!
 
Old 11-06-2003, 11:21 AM   #8
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Original Poster
Rep: Reputation: 30
Hello again!

Well, well, I haven't done very much with this, but since yesterday I have been looking into kev82's "badly written c program" I have now two very short programs that give me the terminal width and height, respectively. It would be nice if someone could have a look and comment. I had some big problems with finding out how to treat STDIN_FILENO, but it seems to be enough just to put a 0 there. Is this the way to do it? It works, but that doesn't necessarily mean its right, right?

OK, here is the one that gives me the terminal width, i.e. the number of columns:

Code:
#include <sys/ioctl.h>

int main()
{
    struct winsize ws;

    ioctl(0, TIOCGWINSZ, &ws);
    printf("%d\n", ws.ws_col);

    return 0;
}
Please be kind - this is my first C program ever ...or rather it was kev82's program...but I compiled it...hrm...

Cheers


Last edited by Bebo; 11-06-2003 at 11:54 AM.
 
Old 11-06-2003, 12:20 PM   #9
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
Quote:
I had some big problems with finding out how to treat STDIN_FILENO, but it seems to be enough just to put a 0 there. Is this the way to do it?
It actually is (a little) better to use STDIN_FILENO instead of 0. Suppuse you compile it on a system where stdin is not on filedescriptor 0, but say 5, then the system will #define STDIN_FILENO as being 5. Well, in this case of stdin, this is very unlikely to happen, so it's a non-issue. But making a habit of using symbols #defined by the system header files is a good thing in general as there are many examples where it would cause a problem when compiled on another system, or when some library/kernel-headers are update (with possibly changed #defined symbols).

STDIN_FILENO is #defined in unistd.h, so you need to include that header. Also, it's better to #include stdio.h when you use printf() in the .c file. When you compile your program with all warnings turned on you get a warning about this:

gcc -Wall -pedantic -o winsize winsize.c
winsize.c: In function `main':
winsize.c:9: warning: implicit declaration of function `printf'

So, actually there's nothing really wrong with your program, but as I understand you are learning C, and are asking for comment, I figured you might wanted to know.

I would write your program like:
Code:
#include <stdio.h>
#include <unistd.h> 
#include <sys/ioctl.h>

int main()
{
    struct winsize ws;

    ioctl(STDIN_FILENO, TIOCGWINSZ, &ws);
    printf("%d\n", ws.ws_col);

    return 0;
}
 
Old 11-06-2003, 12:22 PM   #10
jim mcnamara
Member
 
Registered: May 2002
Posts: 964

Rep: Reputation: 34
Try something like this:
Code:
cols=`stty -a | tr -s ';' '\n' | grep "column" | sed 's/columns =//' | sed 's/ //g'`

echo "blah blah" | fold -s -w $cols
 
Old 11-06-2003, 12:51 PM   #11
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Original Poster
Rep: Reputation: 30
Thanks guys, for your comments!

Aha, so I forgot to include unistd.h - that's why it didn't work! And the stdio.h: I removed it since it seemed to work anyway... Well, I'm learning, I'm learning

My plan was to use the stty solution, but I thought it would be nicer - and a bit more general - if I did something in c instead.

Cheers!
 
Old 11-06-2003, 01:00 PM   #12
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
Quote:
Originally posted by Bebo
My plan was to use the stty solution, but I thought it would be nicer - and a bit more general - if I did something in c instead.
If you're making a general solution, and/or you are scripting anyways, I think it's much better to stick with the stty solution, and use the C-thing for learning C only.
 
Old 11-06-2003, 04:35 PM   #13
Bebo
Member
 
Registered: Jul 2003
Location: Göteborg
Distribution: Arch Linux (current)
Posts: 553

Original Poster
Rep: Reputation: 30
Yeah, maybe that would get the scripts more transparent... Well, jim mcnamara's example is nice, but it didn't really work; here's my solution:

Code:
stty -a | tr -s ';' '\n' | grep "column" | sed s/'[^[:digit:]]'//g
 
Old 11-06-2003, 04:41 PM   #14
jim mcnamara
Member
 
Registered: May 2002
Posts: 964

Rep: Reputation: 34
The exact output format of stty -a varies - mine was on HPUX. The RH linux box has a memory issue. GLad you got what you needed.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Question about running a program from terminal window ganoo Linux - Newbie 7 11-01-2010 12:44 PM
sheel scripting (open new terminal and print in it) chunlee Linux - Newbie 2 10-15-2004 01:33 PM
How can a bash script findout the width of the terminal window alex.e.c Linux - Software 2 10-14-2004 11:20 AM
Changing Text Size/Terminal Width in Bash TastyWheat Linux - General 2 11-02-2003 11:24 PM
Scripting KDE to change window decorations meeshka Linux - Software 2 08-05-2003 06:03 PM


All times are GMT -5. The time now is 02:30 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration