1

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

Festivejelly
  • 670
  • 2
  • 12
  • 30
  • 1
    If you could modify `ICE` you could add a qualifier so that it would use [`Lib$Set_Symbol`](http://h71000.www7.hp.com/doc/73final/5932/5932pro_038.html) to save the output in the symbol of your choice. Alternatively, redirect output to a temporary file and then read the contents of the file back into a symbol. A bit clumsy, but effective. – HABO Jul 08 '14 at 15:58

5 Answers5

1

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
alegria
  • 1,290
  • 14
  • 23
  • 1
    'say' is not a standard OpenVMS command, albeit a frequently used symbol. But yeah... $ pipe write sys$output "Hi" > tmp.tmp – Hein Jul 08 '14 at 12:45
1

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 ... .

HABO
  • 15,314
  • 5
  • 39
  • 57
  • Actually, DEFINE/USER is 'single shot' just for the live of the next executable, no need to de-assign. Also, if re-assigning SYS$OUTPUT does not do it, try SYS$ERROR or even SYS$COMMAND, SYS$INPUT. – Hein Jul 08 '14 at 12:42
  • 1
    @Hein - Right you are! Details from 30 years ago seem to be slipping away, but the right hand still knows the EDT keypad. – HABO Jul 08 '14 at 13:29
  • Ive tried reassigning the sys$output as you can see in my edit. Seems to work fine when I call it via the emulator. But through my C# library or the Java one nothing is output. – Festivejelly Jul 08 '14 at 14:01
  • When you take the `ON ERROR` path you skip over the `DEASSIGN`. Add another `DEASSIGN` to the error handler. (Or a `FINE` which ought to be the opposite of `DEFINE`.) – HABO Jul 08 '14 at 14:05
  • So if I have a VMS method that shows what directory im in... called SHOW that takes a parameter I could capture the output of that in a text file? Ie: $SHOW DEFAULT/OUTPUT=LOG.TXT ? – Festivejelly Jul 09 '14 at 09:17
  • 1
    @Jonkers - The lexical function [`f$environment( "DEFAULT" )`](http://h71000.www7.hp.com/doc/83final/9996/9996pro_93.html) will return the current default directory. You can assign the value directly to symbol. – HABO Jul 09 '14 at 12:29
0

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?

user2116290
  • 1,062
  • 5
  • 6
  • Hello user2116290 thanks for the answer. Basically i'm using a C# SSH2 library to send commands to OpenVMS. I'm a test automation engineer and its how I communicate with the system in order to run batch jobs etc. The reason im using C# is it then plugs into to my automation framework. Ive had some success usings DCLs so far but its a lot different to the languages im used to working with! So essentially I send a command using C# and read the return output then check if the output is as I expected, if that makes sense. – Festivejelly Jul 09 '14 at 08:04
  • Also wont this always just print out "current Test Environment is DISK$DEVELOPERS:[FASTER.DEVELOP]" based on: $ define dcl$path sys$disk[] $ ice show current Test Environment is DISK$DEVELOPERS:[FASTER.DEVELOP] $ The environment isnt always the same. Its set earlier on by using ICE SET – Festivejelly Jul 09 '14 at 09:01
  • I interpret that you are using C# on a non-VMS platform and you use ssh2 to send DCL commands to a VMS system. That's hidden in C# in the class vms and the method ICETo. Presumed the VMS system is named VMSBOX and your DCL command procedure is named ICE_WRAPPER.COM, ICETo does something similar to the command line 'ssh VMSBOX "@ice_wrapper FASTER"'. From what I read, ICE SET FASTER prints the shown 6 lines starting with "Initialising"... I guess you got that in the string variable myResult, correct? I guess that ICE SHOW prints the last, 6th line of that output: the string you want in C#. ... – user2116290 Jul 09 '14 at 15:29
  • ... Whether you need that in a VMS/DCL variable is a different question: it seems you don't. And maybe you don't need such a wrapper at all. Maybe your ICETo method can do an equivalent of 'ssh VMSBOX "ICE SET FASTER"' followed by an 'ssh VMSBOX "ICE SHOW"'. Or even a 'ssh VMSBOX "pipe ICE SET FASTER |search sys$pipe current"'. And your C# code needs to check the results for errors - as printed/shown by VMS - and pick up the wanted result. I'm sure there is more to it, because I don't have the full picture and because the error codes from VMS, i.e. from the "EXIT 2" command, ... – user2116290 Jul 09 '14 at 15:37
  • ... very likely will not make it into a variable in C#. Error handling may require to filter/parse the VMS output in C#. – user2116290 Jul 09 '14 at 15:38
  • Obviously my example wasn't clear. It is a hack showing how to get an output of a program into a DCL variable. The first two code sections just try to fake your environment, an ICE command, so that I could test my hack in my environment with "your commands". If you want to make use of this hack, you only need (to look at) the three other code sections. The hack requires the ICE SHOW command to always print one line with "current" being the first word on that line. – user2116290 Jul 09 '14 at 15:44
  • Thanks for taking the time to explain that user2116290 (catchy name by the way) I think you're right actually maybe I should just read back the whole thing and parse through it in my C# code. My issue was the way the code was outputted was a bit messy really. – Festivejelly Jul 10 '14 at 13:44
  • I would upvote your answer but I dont have enough rep, ive marked Habo's as the solution as it does exactly what I need it to do. Although you have helped me a great deal with your answers so kudos for you. – Festivejelly Jul 10 '14 at 13:45
0

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

Fran
  • 21
  • 2
0

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
SajithP
  • 592
  • 8
  • 19