Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

DCL script to sound BELL without scrolling terminal

Francis Gribbin
Occasional Contributor

DCL script to sound BELL without scrolling terminal

I want to amend a old system so that when a severe error occurs at startup it displays a helpful warning message and to draw attention to the message it beeps repeatedly for 60 seconds before continuing to start up with reduced functionality.

My first thought was to put

WRITE SYS$OUTPUT BELL

in a loop. This gives me beeping but unfortunately every write causes a line feed on my 24 line DECTerm and so the
helpful warning message gets scrolled out of
visibility.

Any ideas on stopping the scrolling?

For now I rewrite the whole 20 line help text
every 10 seconds with a beep.

Note that I have BELL defined as per a
Hoffman Labs example

BELL = "*"
BELL[0,8] = 7

With more effort I could send the messages to our standard logging system (based on syslog), but I was hoping for something quick and easy.
7 REPLIES
Joseph Huber_1
Honored Contributor

Re: DCL script to sound BELL without scrolling terminal

Try this:

$ BELL = " "
$ BELL[0,8] = 7
$ ESC = " "
$ ESC[0,8]=27
$ curup = ESC+ "[A"
$loop: write sys$output curup,bell
$ goto loop

This even works on an Xterm.

Real VTn terminals could do it more fancy:
one could enable the status line, and put the bell there without destroying or scrolling the main screen content.
But I don't have a VT manual at hand right now to find the right sequences.
http://www.mpp.mpg.de/~huber
Steven Schweda
Honored Contributor

Re: DCL script to sound BELL without scrolling terminal

Have you tried using this trick?:

read /prompt = /time_out = 0

I haven't tried it with a BEL, but that's the
usual way of suppressing the usual line
advance in terminal output.

I figure that they'll add a /NONEW_LINE to
WRITE about the same time as they add SHOW
VERSION, so I'm not holding my breath.
Joseph Huber_1
Honored Contributor

Re: DCL script to sound BELL without scrolling terminal

On a real VT320+ or a VMS DECTerm, this works:

$ BELL = " "
$ BELL[0,8] = 7
$ ESC = " "
$ ESC[0,8]=27
$ curup = ESC+ "[A"
$!loop: write sys$output curup,bell
$ on conttrol_y then goto done
$loop:
$ write sys$output eSc,"[1$}",ESC,"[2$~"
$ write sys$output "this is the status line.",bell
$ goto loop
$done:
$ write sys$output eSc,"[0$}"
$ write sys$output "Here we are back."

This displays the text (including bell) in the status line until done: is reached, where the display is switched back to the main screen.
http://www.mpp.mpg.de/~huber
Hoff
Honored Contributor

Re: DCL script to sound BELL without scrolling terminal

Do consider logging the errors somewhere more consistently available to the support staff (rather than upon what is clearly an ephemeral terminal display), and some effort on DCL or other code to dispatch the errors to the user(s) that may well be out of earshot of the errors.

Startup logging (established via the STARTUP_P2 system parameter) can be used and useful here, as more immediate notifications via MAIL, or syslog, push notifications via XMPP, HTML5 Notifications or whatever protocols out to modern mobile clients, or whatever reporting mechanisms might be in use at the site.

Conceivably, the whole of the startup log could end up posted on a web server, possibly also with a scan for "new" errors that also gets posted to the web server. (It'd be nice if VMS actually included a web server, but there are ways to implement that on VMS or to toss the information over to a more, um, encompassing server operating system.

At its simplest...

$ MAIL whatever.txt -
/SUBJECT="whatever" -
"whomever@example.com"

or

$ MAIL whatever.txt -
/SUBJECT="whatever" -
"@VmsMailDistList"

or some such. Or a little more, for sending out a push.

Yes. Bells are easy. But inevitably and as you've already discovered, important information inevitably scrolls off these pesky old terminal displays.
Steven Schweda
Honored Contributor

Re: DCL script to sound BELL without scrolling terminal

> Do consider [...]

But working on the BEL problem is more fun.

alp $ type bel.com
$!
$! Ring the terminal bell P1 times at P2 intervals.
$! Defaults: P1 = 1, P2 = 00:00:01.
$!
$ if (p1 .eqs. "") then p1 = 1
$ if (p2 .eqs. "") then p2 = "00:00:01"
$!
$ bel = ""
$ bel[0, 8] = %x07
$!
$ loop_top:
$ read /error = read_err /prompt = 'bel' /time_out = 0 sys$command line
$ read_err:
$ p1 = p1- 1
$ if (p1 .gt 0)
$ then
$ wait 'p2'
$ goto loop_top
$ endif
$!
John Gillings
Honored Contributor

Re: DCL script to sound BELL without scrolling terminal

Francis,

Much as I like Steven's READ/PROMPT hack, there are some things that DCL is good at, and then there's everything else. Sending unformatted binary output to a terminal is part of "everything else". For proper, fine grained control of I/O you need to use system services directly, or through an HLL RTL.

Even if you don't have a compiler license, you can always use MACRO32 to generate any output you want. The code will work on any OpenVMS system. Don't be afraid of MACRO, it's just another programming language, and for simple tasks like this is can be as compact as just about anything else. I've attached a sample. Even with code to read and parse a command line to control the count, it's not much longer than Steven's DCL example.

Download the attachment and rename it to BELLS.MAR, then

$ MACRO BELLS
$ LINK BELLS
$ MCR SYS$DISK:[]BELLS

it will send bells to the terminal at 1 second intervals, with no carriage control. Replace "SYS$DISK:[]" with an absolute directory name for general use.



A crucible of informative mistakes
John Gillings
Honored Contributor

Re: DCL script to sound BELL without scrolling terminal

Francis,

On second thoughts, I realise that Steven's idea can be exploited for more functionality... First we can use the /TIME_OUT as the timer, rather than WAIT, and, code it so if the user hits RETURN the beeps stop before the counter is reached.

$ count=F$INTEGER(p1)+1
$ int=F$INTEGER(p2) ! in seconds
$ IF int.LE.0 THEN int=1
$ bel[0,8]=7
$ SET NOON
$ Loop: count=count-1
$ IF count.GE.0 THEN READ/ERROR=Loop/PROMPT="''bel'"/TIME_OUT='int' SYS$COMMAND in

Note that using F$INTEGER means that the READ command is valid regardless of user input. Non-numeric input results in default count and interval.
A crucible of informative mistakes