1826312 Members
3689 Online
109692 Solutions
New Discussion

DCL

 
Bjay
Advisor

DCL

could some one tell how to pass a command output
to an variable

I shall be thank full if you share some DCL scripting guide/book/document

thanks
11 REPLIES 11
Robert Gezelter
Honored Contributor

Re: DCL

Bjay,

The simplest way to get the output of a command to a place where it can be read and analyzed is to use the ASSIGN/USER_MODE to route the logical name SYS$OUTPUT to a temporary file.

For an introduction to logical names, see "Logical Names (Part 1)", part of The OpenVMS Consultant series of columns on OpenVMS.org (see http://www.openvms.org/gezelter ).

The "DCL Dictionary" manual is available on the OpenVMS www site at http://h71000.www7.hp.com/doc/83final/9996/9996pro.html

- Bob Gezelter, http://wwws.rlgsc.com
Hoff
Honored Contributor

Re: DCL

You're not on Unix, and OpenVMS DCL redirection is comparatively weak. And there are some wrinkles here between DCL symbols and logical names, and subprocesses.

In general, this doesn't work. Symbols are "bigger" on recent OpenVMS releases, but not big enough to contain the output from many DCL commands.

The OpenVMS User's Guide is the manual you want to read here. This is in the OpenVMS documentation set.

http://www.hp.com/go/openvms/doc

That material will help you understand symbols and logical names and how to deal with /OUTPUT qualifiers and command redirection and such.

The OpenVMS Frequently Asked Questions (FAQ) has how to pass command output around using the PIPE command and logical names. There's a copy of the FAQ here:

http://www.hoffmanlabs.com/vmsfaq/

There's another book around, _Writing Real Programs in DCL_ by Paul Anagnostopoulos and somebody named Hoffman, but that book is presently out of print and used copies of the second edition are reportedly expensive. It's now conceivable that this book might come back into print if there's enough demand, though not through the fine folks over at the Elsevier Digital Press imprint; the previous publishers.

Hein van den Heuvel
Honored Contributor

Re: DCL

You may want to describe the specific problem you want to address. As replied above, there is no common, single solution. Many folks parse file output, several commands having a /OUT qualifier. Some commands leave DCL symbols (SEARCH) to use. Some use a PIPE construct to snarf output and put it into a logical name.

But most importantly you need to realize that often you do NOT need a command. DCL has a set of powerful LEXICAL to do what on other platforms (Unix) is done using a command.
For example, check out HELP LEXI F$SEARCH as a (better!) alternative to capture the DIRECTORY command output. Ans G$GETDVI and F$FILE and so on.... Check HELP and... RTFM!

Hein.
The Brit
Honored Contributor

Re: DCL

Try using the "PIPE" command. For example, consider the command;

$ dir/size=all/grand [...]*.*.*

Grand total of 38 directories, 697 files, 26981/71686 blocks.

Now lets say you want to assign the #of files and total blocks to symbols to use within a script. If P1 is the directory listing ("[...]*.*.*"), then the following command will define the symbols; NFiles = "number of files", and NBlks = Total Blocks.

$ Pipe Dir/Size=all/grand 'P1' | (Read Sys$Input Line ; Read Sys$Input Line ; -
Files = f$elem(5," ",Line) ; -
Blks = f$elem(1,"/",f$elem(7," ",Line)) ; -
define/job/NoLog Nfiles &files ;-
define/job/NoLog Nblks &blks)
$ Nfiles == F$TrnLnm("NFiles","Lnm$Job")
$ NBlks == F$TrnLnm("NBlks","Lnm$Job")

Its a bit clunky, but it is very flexible.

Dave.
Hein van den Heuvel
Honored Contributor

Re: DCL

Dave's PIPE example but done in PERL ...

$ perl -e "for (qx(dir/size=all/grand *.*)){ if (/(\d+) fil.*\/(\d+)/) { $ENV{files}=$1; $ENV{blocks}=$2}}"

$ show log files, blocks
"FILES" = "514" (LNM$PROCESS_TABLE)

"BLOCKS" = "421728" (LNM$PROCESS_TABLE)
$


Same thing using those LEXICALS and a DCL loop:

-----------------------
$files == 0
$blocks == 0
$loop:
$ file = F$SEARCH ("*.*;*")
$ IF file .EQS. "" THEN EXIT
$ files == files + 1
$ blocks == blocks + F$FILE(file,"ALQ")
$ GOTO loop
--------------------------


$SHOW SYMBOL files ...

fwiw,
Hein.


Steven Schweda
Honored Contributor

Re: DCL

> You're not on Unix, [...]

I agree. On UNIX, it often makes sense to
use the `` or $() notation in a script to
collect the output from some command. On VMS
it seldom does. DCL has lexical functions
which can be used in expressions, and these
are more often the better way to do things.

For example, on UNIX, one might try to parse
"df" output to find the free space on a file
system. On VMS, it makes little sense to try
the same thing with SHOW DEVICE /FULL output
when the F$GETDVI lexical function can do it
easily:

alp $ write sys$output f$getdvi( "dka0:", "freeblocks")
16733466

> You may want to describe the specific
> problem [...]

Another good idea. Asking how to implement a
particular poor solution to a problem is
often less useful than asking how to solve
the actual problem.
Bjay
Advisor

Re: DCL

here is what I am doing

1. I have a recording of monitor system command which is taken after every 5 mins
$

and this output is stored into files with time stamp in there name

2. I have to generate a report of last one week disk IO's
so I create a list of monitor record files into a list file
$ dir /since= /before= /column=1 /out=dir.lis

3. then I read this file line by line and parse it to monitor command

$ open /read rec dir.lis
$ rdloop:
$ read /end_of_file=endit rec val
$ define /user sys$output monrep.out
$ pipe monitor disk /input='val | sea sys$input dka0
$ goto rdloop
$ append monrep.out;* monrep.report

4. then I read the monrep.report file and fetch out the desired information
$open /read inpt monrep.report
$ read /end_of_file=clsit inpt val2
$ val2=f$edit(val2,"compress,trim")
$ dsk=f$element(0,"",val2)
$ ios=f$element(4,"",val2)

QUERY
========
IN STEP 3 WHERE I AM DEFINING THE OUTPUT TO A FILE TO WRITE TO THE FILE IS THERE OTHER WAY TO DO THAT
Craig A
Valued Contributor

Re: DCL

I'd have thought it would be easier to simply run MONITOR/RECORD contionuously and then pull out the statistics you want with a MONITOR/INPUT

Unless I misunderstood what you are trying to achieve....

Craig
Bjay
Advisor

Re: DCL

these monitor recording files are of past we want to analyze the IO data of past
Hein van den Heuvel
Honored Contributor

Re: DCL


Ah, now we have a specific, and I think even a tricky question.

Yikes, what an unpleasant task.
Mopping up after a poor past setup.
Be sure to check out T4 for the future!

So anyway, they must have created those files with something like:

$date = f$extract(0,16,f$cvtime()) -"-"-"-"-" "-":"-":"
$end = f$cvti("+0:1:0","ABSOLUTE")
$moni/end=&end/rec='date'.mon/nodisp disk

?


>> IN STEP 3 WHERE I AM DEFINING THE OUTPUT TO A FILE TO WRITE TO THE FILE IS THERE OTHER WAY TO DO THAT

Well, you could add further pipe segments, but it gets really nasty quickly. Too hard!

Next best _should_ be to be able to not to create the individual output files, but just make the output append with a ">>" style operator. But DCL does not have that.
For non-pipe situations you can pre-open a file in DCL, and use that logical name as output device, but that does not work in pipe it seems (process permanent file in the wrong process).

So IF I were to use only DCL for this mission then I would go the hard route, as you outlined already.

Mind you... I would NOT use DIR/BEF to select files which are known to have a timestamp. Why become dependent on the file dates when you can avoid it?

I would use a loop along the lines of:

$loop:
$ file = f$search("*.mon")
$ IF file .EQS. "" THEN GOTO done
$ date = F$EXTR(1,12,file) ! Adapt
$ IF date .LT. "200901010101" THEN GOTO loop
$ files = files + 1
$ PIPE MONI/INPU='file'/DISP=...


But then, I would not use DCL for this task.
I would use PERL.
It will allow me to do much more with the data gathered, and it will not mind dealing with decimal values.

---------------------- test.pl -----------
use strict;
use warnings;
my $files = 0;
for my $file (<*.mon>) {
my $date = substr($file,0,12); # adapt
next if $date lt "200901010101";
$files++;
my ($time, $disk, $rate);
for (qx(MONI/INPU=$file/DISP=SYS\$OUTPUT DISK)) {
$time = $1 if /^\s+(\d+-\S+\s+\S+)/;
if (/DKA0/) {
m/^(\S+)\s.*?\s[0-9.]+\s+([0-9.]+)\s+/;
$disk = $1;
$rate = $2;
print qq($time $disk $rate\n);
}
}
}
print qq(Processed $files files.\n);
-------------------

$perl test.pl
:
11-MAR-2009 07:54:57.67 $8$DKA0: 0.70
11-MAR-2009 07:55:00.67 $8$DKA0: 0.70
11-MAR-2009 07:55:03.68 $8$DKA0: 0.70
11-MAR-2009 07:55:06.68 $8$DKA0: 0.70
11-MAR-2009 07:55:09.69 $8$DKA0: 0.70
11-MAR-2009 07:55:12.69 $8$DKA0: 0.69
Processed 5 files.



Hoff
Honored Contributor

Re: DCL

I'd pitch this home-grown monitoring environment and move to T4, and not spend any more time on the home-grown stuff than I could manage. Build on T4 where you need to.

The f$cvtime lexical function with the "COMPARISON" argument is your friend here, as is the f$file_attributes lexical with the "CDT" argument for the file creation date.

Don't try to program with Unix and bash designs on OpenVMS; you'll end up frustrated and confused.

And do please acquire and read the Smart Questions FAQ. Terse questions will quite often get you entirely correct -- and somewhere between misleading and entirely wrong -- answers. That reading effort will save everybody involved some time, it will get you the answers you need more quickly, and (more subtly) it'll help you in your career development; simply knowing how to ask good questions can be key to advancement and job promotions.