4

This question is for AIX 7

I have been working on a monitor which will display several pages of text. Initially the end user wanted a scrolling list for which I constructed this:

IFS=''; cat plfeed | while read line; do echo $line; perl -e 'select(undef,undef,undef,.8)'; done

The end user has decided that they would rather display a page (24 lines) of output for a set amount of time (20 seconds for example). I know that more will let me display a page at a time, but it requires keyboard input which is not acceptable for my use-case.

tldr;

How can I automate the 'more' command, or build a similar function that will sleep between pages and then automatically advance?

5

This fairly standard awk should be ok on AIX

awk '{if(NR>1 && NR%24==1)system("sleep 20");print}'

As mentioned in the comments, if you want to exit on interrupt, you can replace the system() by

{if(system("sleep 20"))exit}

but it might not work on your OS.

| improve this answer | |
  • 1
    Nice +1. You could make it a bit shorter: awk '!(NR%24) { system("sleep 20") } 1'. This is still very portable. – Thor May 17 '16 at 18:47
  • 1
    You could add a check of the system() return value. If it is non-zero, exit, allowing the user to quit with Ctrl-C or `Ctrl-\`. – Thor May 17 '16 at 18:54
  • 1
    @Thor I didn't want the first page to be exceptionally 23 lines only, hence the test against 1. And I tried testing the return code from system() on interrupt but it was always 0 on my fedora! ... Tried on a debian and it worked correctly. Bizarre. – meuh May 17 '16 at 18:57
  • I see. With regards to the return value, I was testing it with nawk where it sort of works. I see the same strange issue with zero return value with GNU awk. mawk on the other hand intercepts the signal and quits. So not a very portable solution. – Thor May 17 '16 at 20:05
  • Thanks -- that made it even more perfecter: IFS=''; cat filename | awk '{if(NR>1 && NR%24==1){if(system("sleep 20"))exit};print}' – Alan May 17 '16 at 20:53
2
#!/usr/bin/env expect 
set timeout 20
spawn -noecho man autoexpect
while 1 {
  expect {
    timeout { send " " }
    -ex "(END)" { exit }
  }
}
| improve this answer | |
  • Thanks. Is there a way to format that as a single line command? – Alan May 17 '16 at 17:29
  • 1
    That should be #! /usr/bin/expect -f or -- instead of -f. Please don't spread the #! /usr/bin/env disease any further. It's bad enough that it's almost universal in the python sphere...python users might not care about arbitrary breakage of the #! line (e.g. so that the interpreter can't take args, amongst several other problems) but users of other languages still do. – cas May 18 '16 at 2:46
  • I will continue to use env as figuring out which expect to use on which platform would be needlessly complicated (it's not /usr/bin/expect on either of my primary operating systems). I do agree about the python disease part, though. – thrig May 18 '16 at 14:01
1

This addresses the nature OP's question using a similar awk solution as meuh. I've made the following changes:

  1. Exit via Ctrl+c.
  2. Use $LINES to get height of terminal.
  3. Works on Linux and Mac OSX.
  4. Added documentation and explanations.
awk -v x=$LINES 'NR % x == 0 && system("sleep 20"){exit} 1'
#    ^^^^^^^^^^  ^  ^^^^^^^^      ^                      ^
#       |        |  |             |                      |
#       |        |  |             |                      |
#       |        |  |             |                      +
#       |        |  |             |   f) pattern-action block which
#       |        |  |             |      prints the current line.
#       |        |  |             |        - Pattern is Truethy.
#       |        |  |             |        - Action is empty
#       |        |  |             |          defaulting to `{print}`
#       |        |  |             |
#       |        |  |             +
#       |        |  |   d) `system` function returns exit code `0` when
#       |        |  |       successful and non-zero on 'ctrl-c'.
#       |        |  |
#       |        |  |   e) `0` evaluates to false, so `exit` will not
#       |        |  |       execute until `ctrl-c` is triggered.
#       |        |  +
#       |        | c) When line number is evenly divisible
#       |        |    by x (the terminal height)
#       |        |    sleep for 1 second.
#       |        | 
#       |        | 
#       |        +
#       |   b) NR current line number.
#       |
#       +
# a) Set variable `x` to Bash variable $LINES.
#    $LINES is set to height of current terminal.
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.