How to store a command output in OpenVMS

6.1k views Asked by At

Im having an issue writing a DCL in OpenVMS in that I need the DCL to call a command and capture its output (but not output the output to the screen) Later on in the DCL I then need to print that output I stored.

Heres an example:

ICE SET FASTER !This command sets my environment to the "Faster" environment.

The above command outputs this if executed directly in OpenVMS:

Initialising TEST Environment to FASTER
--------------------------------------------------------------------------------
  Using Test Search rules FASTER   
  Using Test Search rules FASTER   
--------------------------------------------------------------------------------
dcl>

So I created a DCL in an attempt to wrap this output in order to display a more simplified output. Heres my code so far:

 !************************************************************************
 $ !* Wrapper for setting ICE account. Outputs Environment
 $ !************************************************************************
 $ on error then goto ABORT_PROCESS
 $ICE_DCL_MAIN:
 $ ice set 'P1'
 $ ICE SHOW
 $ EXIT
 $ABORT_PROCESS:
 $ say "Error ICING to: " + P1
 $ EXIT 2
 [End of file]

In the lines above ICE SET 'P1' is setting the ice environment, but I dont want this output to be echoed to VMS. But what I do want is to write the output of $ICE SHOW into a variable and then echo that out later on in the DCL (most of which ive omitted for simplification purposes)

So what should be outputted should be:

current Test Environment is DISK$DEVELOPERS:[FASTER.DEVELOP]

Instead of:

Initialising TEST Environment to FASTER
--------------------------------------------------------------------------------
   Using Test Search rules FASTER   
   Using Test Search rules FASTER   
--------------------------------------------------------------------------------
current Test Environment is DISK$DEVELOPERS:[FASTER.DEVELOP]

Ive had a look through the manual and im getting a bit confused so I figured I tried here. Id appreciate any pointers. Thanks.

EDIT

Here is what ive come up with after the comments, the problem im having is when I connect to VMS using an emulator such as SecureCRT the correct output is echoed. But when I run the DCL via my SSH2 library in .NET it doesnt output anything. I guess thats because it closes the SYS$OUTPUT stream temporarily or something?

$ !************************************************************************
$ !* Wrapper for setting ICE account. Outputs Environment
$ !************************************************************************
$ on error then goto ABORT_PROCESS
$ICE_DCL_MAIN:
$ DEFINE SYS$OUTPUT NL:
$ ice set 'P1'
$ DEASSIGN SYS$OUTPUT
$ ice show
$ EXIT
$ABORT_PROCESS:
$ say "Error ICING to: " + P1
$ EXIT 2
[End of file]

EDIT 2

So I guess really I need to clarify what im trying to do here. Blocking the output doesnt so matter so much, im merely trying to capture it into a Symbol for example.

So in C# for example you can have a method that returns a string. So you'd have string myResult = vms.ICETo("FASTER"); and it would return that and store it in the variable.

I guess im looking for a similar thing in VMS so that once ive iced to the environment I can call:

$ environment == $ICE SHOW

But I of course get errors with that statement

5

There are 5 answers

6
HABO On BEST ANSWER

The command $ assign/user_mode Thing Sys$Output will cause output to be redirected to Thing until you $ deassign/user_mode Sys$Output or next executable image exits. An assignment without the /USER_MODE qualifier will persist until deassigned.

Thing can be a logical name, a file specification (LOG.TXT) or the null device (NLA0:) if you simply want to flush the output.

When a command procedure is executed the output can be redirected using an /OUTPUT qualifier, e.g. $ @FOO/output=LOG.TXT.

And then there is piping ... .

1
alegria On

You can redirect the output to a temp file and then print its content later:

$ pipe write sys$output "hi" > tmp.tmp
$ ty tmp.tmp
8
user2116290 On

VMS is not Unix, DCL is not Bash: you can not easily set a DCL symbol from the output of a command.

Your ICE SHOW prints one line, correct? The first word is always "current", correct?

So you can create a hack.

First let me fake your ICE command:

$ create ice.com
$ write sys$output "current Test Environment is DISK$DEVELOPERS:[FASTER.DEVELOP]"
^Z
$

and I define a dcl$path pointing to the directory where this command procedure is so that I can use/fake the command ICE

$ define dcl$path sys$disk[]
$ ice show
current Test Environment is DISK$DEVELOPERS:[FASTER.DEVELOP]
$

Now what you need, create a command procedure which sets a job logical

$ cre deflog.com
$ def/job/nolog mylog "current''p1'"
^Z
$

And I define a command "current" to run that command procedure:

$ current="@deflog """

Yes, you need three of the double quotes at the end of the line!

And finally:

$ pipe (ice show | @sys$pipe) && mysym="''f$log("mylog")'"
$ sh symb mysym
  MYSYM = "current Test Environment is DISK$DEVELOPERS:[FASTER.DEVELOP]"
$

On the other hand, I don't know what you are referring to C# and Java. Can you elaborate on that and tell us what runs where?

0
Fran On

You can try using: DEFINE /USER SYS$OUTPUT NL:. It works only for the next command and you dont need to deassign.

0
SajithP On

Sharing some of my experience here. I used below methods to redirect outputs to files.

Define/Assign the user output and then execute the required command/script afterwards. Output will be written to .

$define /user sys$output <file_path>
execute your command/script

OR

assign /user <file_path> sys$output
execute your command/script
deassign sys$output

To re-direct in to null device like in Unix (mentioned in above answers), you can use 'nl:' instead of

define /user sys$output nl:
or
assign /user nl: sys$output