• Capturing DCL output in symbol

    From David Meyer@21:1/5 to All on Sat May 10 10:53:57 2025
    I am working on a DCL script where I want to capture output from a
    command in a symbol for manipulation later in the script.

    I have it working by using the /OUTPUT qualifier on the command to put
    the output (just 1 line in this case) into a temporary file, then later
    use READ to put the contents of the temporary file into a symbol.

    I was wondering if I could use PIPE to do the same thing without having
    to create and later clean up the temporary file, but so far I have been
    unable to fine a way to get READ inside a PIPE to set a symbol that's accessible outside the PIPE command.

    READ's help says that it creates the symbol in the local symbol table,
    but is there anyway to get READ to set a global symbol?
    --
    David Meyer
    Takarazuka, Japan
    papa@sdf.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Henry Crun@21:1/5 to David Meyer on Sat May 10 08:04:57 2025
    On 10/05/2025 7:32, David Meyer wrote:
    I found that one way to do it is to put all the processing that uses the command output inside subshells in the same PIPE command.

    One shortcoming of this method is that it's very easy to go over the
    maximum command element length allowed inside the PIPE. For my
    procedure, I was able to get around this by choosing lexical functions
    to minimize the length of the PIPE command.

    Any other way to do this?

    try e.g.
    $ count=$( dir *.sh | wc -l )
    $ echo $count
    25

    HTH

    --
    -- No Micro$oft products were used in the URLs above, or in preparing this message. Recommended reading:
    http://www.catb.org/~esr/faqs/smart-questions.html#befor

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Meyer@21:1/5 to All on Sat May 10 13:32:13 2025
    I found that one way to do it is to put all the processing that uses the command output inside subshells in the same PIPE command.

    One shortcoming of this method is that it's very easy to go over the
    maximum command element length allowed inside the PIPE. For my
    procedure, I was able to get around this by choosing lexical functions
    to minimize the length of the PIPE command.

    Any other way to do this?
    --
    David Meyer
    Takarazuka, Japan
    papa@sdf.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Meyer@21:1/5 to Henry Crun on Sat May 10 15:06:44 2025
    Henry Crun <mike@rechtman.com> writes:

    try e.g.
    $ count=$( dir *.sh | wc -l )
    $ echo $count
    25

    I get an undefined symbol error for \$\ on OpenVMS V8.3. Does your trick require a newer version of VMS?

    --
    David Meyer
    Takarazuka, Japan
    papa@sdf.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Meyer@21:1/5 to All on Sat May 10 15:46:08 2025
    ... or are you using bash?
    --
    David Meyer
    Takarazuka, Japan
    papa@sdf.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Henry Crun@21:1/5 to David Meyer on Sat May 10 10:56:14 2025
    On 10/05/2025 9:06, David Meyer wrote:
    Henry Crun <mike@rechtman.com> writes:

    try e.g.
    $ count=$( dir *.sh | wc -l )
    $ echo $count
    25

    I get an undefined symbol error for \$\ on OpenVMS V8.3. Does your trick require a newer version of VMS?

    Apologies!!
    Ignore my post - I was in the wrong newssgroup.

    ...Senior moment ;-(

    --
    -- No Micro$oft products were used in the URLs above, or in preparing this message. Recommended reading:
    http://www.catb.org/~esr/faqs/smart-questions.html#befor

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Meyer@21:1/5 to Henry Crun on Sat May 10 17:47:05 2025
    Henry Crun <mike@rechtman.com> writes:

    Apologies!!
    Ignore my post - I was in the wrong newssgroup.

    ...Senior moment ;-(

    No worries. Happens to the best of us.

    --
    David Meyer
    Takarazuka, Japan
    papa@sdf.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hb0815@21:1/5 to David Meyer on Sat May 10 13:40:45 2025
    On 5/10/25 03:53, David Meyer wrote:
    ...
    I was wondering if I could use PIPE to do the same thing without having
    to create and later clean up the temporary file, but so far I have been unable to fine a way to get READ inside a PIPE to set a symbol that's accessible outside the PIPE command.
    ...

    Using PIPE: to capture the output of a (DCL) command you need a
    "pipeline", that is you need "|". For each pipeline you get a
    sub-processes. Within the sub-process you can assign a DCL symbol with
    READ. But a symbol in a sub-process is not propagated to the main
    process. You have to take a detour via a logical name in the job table
    to get the symbol value into a symbol of the main process.

    $ del/symb t
    %DCL-W-UNDSYM, undefined symbol - check validity and spelling
    $ pipe show time | -
    (read sys$pipe t ;qt=""""+f$fao("!AS",t)+"""" ;def/job/nolog t &qt) -
    ;t=f$trnlnm("t")
    $ sh symb t
    T = " 10-MAY-2025 10:21:19"
    $

    As you can see, the PIPE command contains a sequence of two pipelines
    and a DCL command. The second pipeline is a subshell. The logical is
    defined in the sub-process of the second pipeline. The subshell is
    required or you will not have access to the symbol read by READ. The DCL command runs in your main process. Translating the logical name into a
    (local) symbol makes its value available in the main process.

    There are limitations. This can only work if the equivalence string of
    the logical name is valid, does not exceed a limit, etc.

    If your output is a DCL token, then you do not need the quoting (in qt).

    And yes, you need the "&" for the "define". If you use 't' the symbol is evaluated when you enter the command and not when the define is executed.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Meyer@21:1/5 to mw40171@mucweb.de on Sun May 11 23:42:44 2025
    hb0815 <mw40171@mucweb.de> writes:

    You have to take a detour via a logical
    name in the job table to get the symbol value into a symbol of the main process.


    That's a great trick. Thanks.

    --
    David Meyer
    Takarazuka, Japan
    papa@sdf.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to David Meyer on Sun May 11 14:17:32 2025
    On 5/9/25 11:32 PM, David Meyer wrote:
    I found that one way to do it is to put all the processing that uses the command output inside subshells in the same PIPE command.

    One shortcoming of this method is that it's very easy to go over the
    maximum command element length allowed inside the PIPE. For my
    procedure, I was able to get around this by choosing lexical functions
    to minimize the length of the PIPE command.

    Any other way to do this?

    It's pretty easy with Perl:

    $ perl -"MVMS::DCLsym" -e "$x=`show time`; VMS::DCLsym->setsym('mysym',
    $x, 'GLOBAL');"
    $ SHOW SYMBOL mysym
    MYSYM == " 11-MAY-2025 14:10:89."

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to bill on Sun May 11 21:15:49 2025
    On 5/11/25 6:24 PM, bill wrote:
    On 5/11/2025 3:17 PM, Craig A. Berry wrote:
    On 5/9/25 11:32 PM, David Meyer wrote:
    I found that one way to do it is to put all the processing that uses the >>> command output inside subshells in the same PIPE command.

    One shortcoming of this method is that it's very easy to go over the
    maximum command element length allowed inside the PIPE. For my
    procedure, I was able to get around this by choosing lexical functions
    to minimize the length of the PIPE command.

    Any other way to do this?

    It's pretty easy with Perl:

    $ perl -"MVMS::DCLsym" -e "$x=`show time`; VMS::DCLsym-
    setsym('mysym', $x, 'GLOBAL');"
    $ SHOW SYMBOL mysym
       MYSYM == "   11-MAY-2025 14:10:89."


    It's probably easy to do in a lot of scripting languages.
    But the original request specified DCL.  Might be he
    expects the script to have to run on machines that only
    have VMS on them.

    On OpenVMS x86, Perl is part of the base install, so it's always there.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Meyer@21:1/5 to Craig A. Berry on Mon May 12 18:01:09 2025
    "Craig A. Berry" <craigberry@nospam.mac.com> writes:

    On 5/11/25 6:24 PM, bill wrote:
    On 5/11/2025 3:17 PM, Craig A. Berry wrote:
    It's pretty easy with Perl:
    [...]

    It's probably easy to do in a lot of scripting languages.
    But the original request specified DCL.  Might be he
    expects the script to have to run on machines that only
    have VMS on them.

    On OpenVMS x86, Perl is part of the base install, so it's always there.


    I'm using primarily OpenVMS on a VAXstation 4000-60, and also wanted to
    make the problem an opportunity to learn more DCL.

    --
    David Meyer
    Takarazuka, Japan
    papa@sdf.org

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Craig A. Berry on Tue May 13 12:18:16 2025
    On 5/11/2025 3:17 PM, Craig A. Berry wrote:
    On 5/9/25 11:32 PM, David Meyer wrote:
    I found that one way to do it is to put all the processing that uses the
    command output inside subshells in the same PIPE command.

    One shortcoming of this method is that it's very easy to go over the
    maximum command element length allowed inside the PIPE. For my
    procedure, I was able to get around this by choosing lexical functions
    to minimize the length of the PIPE command.

    Any other way to do this?

    It's pretty easy with Perl:

    $ perl -"MVMS::DCLsym" -e "$x=`show time`; VMS::DCLsym->setsym('mysym',
    $x, 'GLOBAL');"
    $ SHOW SYMBOL mysym
      MYSYM == "   11-MAY-2025 14:10:89."

    You can probably code a word processor as a one liner
    in Perl ...

    :-) :-) :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Tue May 13 12:16:42 2025
    On 5/10/2025 7:40 AM, hb0815 wrote:
    On 5/10/25 03:53, David Meyer wrote:
    I was wondering if I could use PIPE to do the same thing without having
    to create and later clean up the temporary file, but so far I have been
    unable to fine a way to get READ inside a PIPE to set a symbol that's
    accessible outside the PIPE command.

    Using PIPE: to capture the output of a (DCL) command you need a
    "pipeline", that is you need "|". For each pipeline you get a sub-
    processes. Within the sub-process you can assign a DCL symbol with READ.
    But a symbol in a sub-process is not propagated to the main process. You
    have to take a detour via a logical name in the job table to get the
    symbol value into a symbol of the main process.

    $ del/symb t
    %DCL-W-UNDSYM, undefined symbol - check validity and spelling
    $ pipe show time | -
      (read sys$pipe t ;qt=""""+f$fao("!AS",t)+"""" ;def/job/nolog t &qt) -
      ;t=f$trnlnm("t")
    $ sh symb t
      T = "  10-MAY-2025 10:21:19"
    $

    As you can see, the PIPE command contains a sequence of two pipelines
    and a DCL command. The second pipeline is a subshell. The logical is
    defined in the sub-process of the second pipeline. The subshell is
    required or you will not have access to the symbol read by READ. The DCL command runs in your main process. Translating the logical name into a (local) symbol makes its value available in the main process.

    There are limitations. This can only work if the equivalence string of
    the logical name is valid, does not exceed a limit, etc.

    If your output is a DCL token, then you do not need the quoting (in qt).

    And yes, you need the "&" for the "define". If you use 't' the symbol is evaluated when you enter the command and not when the define is executed.

    That is brilliant!

    I tried stuffing it in a COM file:

    $ vf='f$verify(0)'
    $ pipe 'p1' | -
    (read sys$pipe lin ; qlin=""""+lin+"""" ; def/job/nolog res &qlin) ; -
    'p2'==f$trnlnm("res")
    $ if vf then exit f$verify(1)+1
    $ exit 1

    So I can do:

    $ @cmd2sym "show time" t
    $ sh symb t
    T == " 13-MAY-2025 12:11:57"
    $ @cmd2sym "type z.txt" t
    $ sh symb t
    T == "A"

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert A. Brooks@21:1/5 to All on Wed May 14 03:40:26 2025
    On 5/13/2025 12:16, Arne Vajhøj wrote:
    On 5/10/2025 7:40 AM, hb0815 wrote:

    Using PIPE: to capture the output of a (DCL) command you need a
    "pipeline", that is you need "|". For each pipeline you get a sub-
    processes. Within the sub-process you can assign a DCL symbol with
    READ. But a symbol in a sub-process is not propagated to the main
    process. You have to take a detour via a logical name in the job
    table to get the symbol value into a symbol of the main process.

    That is brilliant!

    That's because hb0815, otherwise known as Hartmut Becker, longtime DEC/CPQ/HPE/VSI VMS Engineer,
    is brilliant.

    --
    -- Rob

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed May 14 09:31:16 2025
    On Sat, 10 May 2025 13:40:45 +0200, hb0815 wrote:

    There are limitations. This can only work if the equivalence string of
    the logical name is valid, does not exceed a limit, etc.

    You have to choose a logical name that won’t clash with any other use in
    any other process in the same job, you have to remember to delete it
    afterwards to avoid clutter ...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed May 14 09:08:00 2025
    On 5/14/2025 5:31 AM, Lawrence D'Oliveiro wrote:
    On Sat, 10 May 2025 13:40:45 +0200, hb0815 wrote:
    There are limitations. This can only work if the equivalence string of
    the logical name is valid, does not exceed a limit, etc.

    You have to choose a logical name that won’t clash with any other use in any other process in the same job, you have to remember to delete it afterwards to avoid clutter ...

    That is not so hard.

    $ vf='f$verify(0)'
    $ reslog = "RES_" + f$unique()
    $ pipe 'p1' | -
    (read sys$pipe lin ; qlin=""""+lin+"""" ; def/job/nolog 'reslog'
    &qlin) ; -
    'p2'==f$trnlnm(reslog)
    $ deas/job 'reslog'
    $ if vf then exit f$verify(1)+1
    $ exit 1

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed May 14 09:20:47 2025
    On 5/14/2025 9:08 AM, Arne Vajhøj wrote:
    On 5/14/2025 5:31 AM, Lawrence D'Oliveiro wrote:
    On Sat, 10 May 2025 13:40:45 +0200, hb0815 wrote:
    There are limitations. This can only work if the equivalence string of
    the logical name is valid, does not exceed a limit, etc.

    You have to choose a logical name that won’t clash with any other use in >> any other process in the same job, you have to remember to delete it
    afterwards to avoid clutter ...

    That is not so hard.

    $ vf='f$verify(0)'
    $ reslog = "RES_" + f$unique()
    $ pipe 'p1' | -
      (read sys$pipe lin ; qlin=""""+lin+"""" ; def/job/nolog 'reslog'
    &qlin) ; -
      'p2'==f$trnlnm(reslog)
    $ deas/job 'reslog'
    $ if vf then exit f$verify(1)+1
    $ exit 1

    Going from the surgeon approach to the caveman approach:

    $ vf='f$verify(0)'
    $ tmpfnm = f$unique() + ".out"
    $ define/nolog sys$output 'tmpfnm'
    $ 'p1'
    $ deas sys$output
    $ ix = 0
    $ open/read f 'tmpfnm'
    $ loop:
    $ read/end=endloop f line
    $ ix = ix + 1
    $ 'p2'_line_'ix' == line
    $ goto loop
    $ endloop:
    $ close f
    $ 'p2'_count == ix
    $ if vf then exit f$verify(1)+1
    $ exit 1

    and:

    $ @cmd2msym "show time" t
    $ sh symb t_*
    T_COUNT == 1 Hex = 00000001 Octal = 00000000001
    T_LINE_1 == " 14-MAY-2025 09:15:57"
    $ @cmd2msym "type z.txt" t
    $ sh symb t_*
    T_COUNT == 3 Hex = 00000003 Octal = 00000000003
    T_LINE_1 == "A"
    T_LINE_2 == "B"
    T_LINE_3 == "C"

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From hb0815@21:1/5 to All on Wed May 14 21:06:44 2025
    On 5/14/25 15:08, Arne Vajhøj wrote:
    On 5/14/2025 5:31 AM, Lawrence D'Oliveiro wrote:
    On Sat, 10 May 2025 13:40:45 +0200, hb0815 wrote:
    There are limitations. This can only work if the equivalence string of
    the logical name is valid, does not exceed a limit, etc.

    You have to choose a logical name that won’t clash with any other use in >> any other process in the same job, you have to remember to delete it
    afterwards to avoid clutter ...

    That is not so hard.
    ...

    Dunno if it is worth the effort (but this is or can be one line):

    $ sh log/job

    (LNM$JOB_821AC8C0)

    "MYSCRATCH" = "USR_SCRATCH:[<username>]"
    "SYS$LOGIN" = "DISK_USER:[DECUSERVE_USER.<username>]"
    "SYS$LOGIN_DEVICE" = "DISK_USER:"
    "SYS$REM_ID" = "528C3CA5:BA72"
    "SYS$REM_NODE" = "i528C3CA5"
    "SYS$REM_NODE_FULLNAME" = "i528C3CA5.<myisp>"
    "SYS$SCRATCH" = "DISK_USER:[DECUSERVE_USER.<username>]"
    $ show symbol t
    %DCL-W-UNDSYM, undefined symbol - check validity and spelling
    $
    $ pipe u=""""+f$unique()+"""" ;show time |(read sys$pipe t ;qt=""""+f$fao("!AS",t)+"""" ;def/job/nolog &u &qt) ;t=f$trnlnm(&u) ;deassign/job &u
    $
    $ show symbol t
    T = " 14-MAY-2025 14:53:51"
    $ sh log/job

    (LNM$JOB_821AC8C0)

    "MYSCRATCH" = "USR_SCRATCH:[<username>]"
    "SYS$LOGIN" = "DISK_USER:[DECUSERVE_USER.<username>]"
    "SYS$LOGIN_DEVICE" = "DISK_USER:"
    "SYS$REM_ID" = "528C3CA5:BA72"
    "SYS$REM_NODE" = "i528C3CA5"
    "SYS$REM_NODE_FULLNAME" = "i528C3CA5.<myisp>"
    "SYS$SCRATCH" = "DISK_USER:[DECUSERVE_USER.<username>]"
    $

    Much more to type and to think about than doing this in bash. And before someone asks, /SYMBOLS is default for PIPE (as for SPAWN).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)