Question
· Jul 29, 2019

Linux / RHEL - Writing Global Value from Cache to STDOUT on the Command Line OS Terminal

Hello,

Is it possible to write global output values to STDOUT, in a similar way to how csession can take routine intput, like below:

 

(In Cache Terminal)

%SYS>d ##class(%SYSTEM.License).ShowSummary()

 

License Server summary view of active key.

 

     Distributed license use:

Current License Units Used =        1

Maximum License Units Used =        1

License Units   Authorized =      200

 

     Local license use:

Current Connections =      1  Maximum Connections =      1

Current Users       =      1  Maximum Users       =      2

 

(From Linux OS Terminal)

[jhipp@test-sbox ~]# csession TEST "##class(%SYSTEM.License).ShowSummary()"

 

License Server summary view of active key.

 

     Distributed license use:

Current License Units Used =        0

Maximum License Units Used =        1

License Units   Authorized =      200

 

     Local license use:

Current Connections =      0  Maximum Connections =      1

Current Users       =      1  Maximum Users       =      2


This does not work, but I am wondering if there is a recommended solution:

 

(Cache Terminal)

%SYS>w ##class(Security.System).AutheEnabledGetStored("SYSTEM")

8304

(Linux OS Terminal)

[jhipp@test-sbox ~]# csession TEST "##class(Security.System).AutheEnabledGetStored("SYSTEM")"

<INVALID ARGUMENT>

[jhipp@test-sbox ~]# csession TEST "w ##class(Security.System).AutheEnabledGetStored("SYSTEM")"

<INVALID ARGUMENT>

 

 

A workaround (that I think is a bit clunky, which is why I am asking):

[jhipp@test-sbox ~]# echo -e "w ##class(Security.System).AutheEnabledGetStored(\"SYSTEM\")\nh" |csession TEST

 

Node: test-sbox, Instance: TEST

 

%SYS>

8304

%SYS>

 

I can parse out the line output with grep or awk, but that is probably not the best way to achieve this.

 

 

Thanks,

- James

Discussion (5)1
Log in or sign up to continue

James, for this one, there is no easy answer. But first, here are some corrections FYI:

  • Since what you're passing in to execute contains quotes ("SYSTEM"), surround that with single quotes instead of double quotes
  • Since the Security.System class is in %SYS, specify the namespace in your command.

So it's this:

csession TEST -U %SYS '##class(Security.System).AutheEnabledGetStored("SYSTEM")'

But the problem is that this expression doesn't output its value, and you can't include "write" at the beginning. You should probably describe exactly what you're trying to do in more detail, and someone here will make a suggestion.

Hey Joel,

Thanks for the input, single quotes is easier than using slashes to escape the double quote characters.

That particular command may not be the best example to accomplish what I am looking for, but it was more of just a general question about the best way to write out global values. For instance, we have a script that checks for Users that exists in Cache, so that requires us to write out a global boolean value for Security.Users.Exists(). And similar things like that.

Thanks,

James

Hello Alexey,

I appreciate your input. This method accomplishes what I mentioned earlier as well in my workaround. I personally do not like using 'EOF' in my scripts  because it can be very sensitive with indentation and whitespace. But regardless, with either method I am going to have to parse out the 5th line of output with awk if I just want to return the true value and not the entire Cache terminal output. 

I would consider your solution a 'workaround' as well , but you are correct this does work. I just did not know if there was a way to only return the global value to STDOUT much like cconsole can do with routine calls.

Thanks,

James

The simplest way to interact from within bash with Caché looks like this: 

#!/bin/bash
...
csession TEST -U%SYS << EOF
set \$namespace="%SYS"
write ##class(Security.System).AutheEnabledGetStored("SYSTEM")
halt
EOF
... next line of your bash script ...

Output of Caché `write` and `zwrite` commands will go to STDOUT. As usual, you can redirect it wherever you want, e.g.

csession TEST -U%SYS << EOF >> /home/james/mysession.log

As parsing csession log can be a nasty task, I usually try to avoid it by construct:

#!/bin/bash
...
tf=/home/file.tmp
...
csession TEST -U%SYS << EOF > /dev/null
open $tf:("NWS"):1 use $tf
write ##class(Security.System).AutheEnabledGetStored("SYSTEM")
close $tf
halt
EOF
...
result=$(cat "$tf")

Hi James,

Agree with you, parsing terminal output is not the smartest solution. I always try to avoid it using intermediate files. E.g. (from real life):

rm -f $mydir/db_temp
NspToCheck=$nspace

csession $instance -U%SYS << EOF > /dev/null
set fn="$mydir/db_temp"
o fn:("WNS"):1 u fn
try {
  zn "$NspToCheck"
  w \$s(\$zu(5)=\$zcvt("$NspToCheck","U"):\$zutil(12,""),1:"$NspToCheck")
} catch {
  w \$p(\$ze,">")_">"
}
c fn
h
EOF

DbQms=$(cat "$mydir/db_temp")

Here the default DB of the namespace $NspToCheck (or $ZError code) is written to $mydir/db_temp file, than it goes to $DbQms shell variable and processed as needed.

Initial answer was amended.