One option would just be a straight telnet session (swap with the IP address of your system):

telnet 1972

If the port is closed, you should get the error: "telnet: Unable to connect to remote host: Connection refused" - but if successful you should get the "Connected to" you'll know it's open. To exit, type <CTRL>] for a telnet prompt, then type 'quit'.

Hope this helps!


I'm not sure if this helps your particular situation, but if it's "OK" to manually tell your container what the local hostname of the host is, then you could try this:

set ip=$SYSTEM.INetInfo.HostNameToAddr("**local_name_NotFQDN**")

with just the local hostname (not the FQDN) of the host machine in quotes... and that should give you the IP address of the active ethernet/wireless adapter. I tried this in a container running IRIS on a Raspberry Pi and the local hostname is "Iris2" (so, it is running Linux, I don't have any container systems running on Windows... sorry!) and this is what I got:

USER> Set ip=$SYSTEM.InetInfo.HostNameToAddr("Iris2")
USER> zw ip

On my network, 172.17.0.x is the internal Docker bridge, 192.168.1.x is my wireless network, and 10.1.2.x is my desktop wired network. (I have many servers, printers & whatnot, so I have multiple VLANs on my home network.) Now... I'm not sure if this is good or bad for your situation, but in my example, if I were to shutdown the container, disable the wireless, hook up an ethernet cable to the network and restart everything, the listed IP from this command would change from the 192.168.1.x to a 10.1.2.x IP address. This could be good if you wanted to know how the main machine was externally connected; or it could be bad if you're using awk/grep/findstr on logs looking for a particular IP. As I said, I'm unsure of your actual use case, so if this had to be portable across several containers and several machines unchanged, this may not help you as you'll manually have to change the machine name in your code.

Hope this helps!

If you have multiple subscript levels, this may help:

SET I=0,G="^test("""")" FOR {SET G=$QUERY(@G) Q:G=""  SET I=I+1 WRITE G,!} WRITE "Total: ",I,!

Here's the data:

set ^test(1)="aa"
set ^test(1,1,1)="aa"
set ^test(2)="aa"
set ^test(2,1)="aa"
set ^test(2,2,1)="aa"
set ^test(3,1)="aa"
set ^test(4,1)="aa"

And here's the output:

Total: 7

If you only wanted the total (especially if the global is much larger) omit the 'WRITE G,!' portion out of the line of code above.

Hope this helps!

I'm not sure I understand the class examples you have listed, but there's a possibility that you may not need to do this in a class.

Ensemble / HealthShare has a couple different ways that you can send a process output to multiple operations. The first is if you're not using any form of data translation, you can send the output right from the BP configuration screen:


Under the Response Target Config Names, I've selected two different targets here, and you can see that the connectivity verifies this - but I'm sending the output to more than two targets! How can that be? Simple, you can also select different targets in the Ensemble Rule Editor - this can be handy if you wanted to apply two different DTL transformations to two different targets. My example is super-simple (as in I'm not applying different rules or DTLs per target) but with multiple Send directives we can specify multiple targets:


You can have different rules with different constraints going to different operations - but I just added a send directive to a sample ruleset to show how to configure multiple targets - and as you can see between the two screenshots how Ensemble is sending the data to 4 different targets in two different ways.

Hope this helps!

Well, everyone has coding styles and ObjectScript offers several different styles - I could have made this prettier (to me, anyway) as I'm more accustomed to the single-letter-command and dot-loop styles... but I tried to keep this in your coding style.

My code isn't pretty - I focused more on making it (barely) functional and demonstrative of the $DATA command - this command will let you know if there's any further subscripts available in a global - documentation page is here:

Anyway, here's my code - I didn't have a chance to create a class method (again, I prefer the older styles) but just copy-paste the code center into your method and it should function. Again, it's not pretty, but it will demonstrate what you need.

If you wanted to make this more efficient, recoding this to handle subscripts recursively would be much shorter and could handle any number of subscripts, not just 3.

    set subscript = ""
    for {
      set subscript = $order(^Book(subscript))
      quit:(subscript = "")
      set moresub = $data(^Book(subscript))
      if moresub=10 {
      set sub2=""
      for {
           set sub2 = $order(^Book(subscript,sub2))
           set moresub2= $data(^Book(subscript,sub2))
           if moresub2=10 {
          set sub3=""
             for {
                 set sub3 = $order(^Book(subscript,sub2,sub3))
                 set moresub3= $data(^Book(subscript,sub2,sub3))
                 if moresub3 = 1 {
                 write !, "subscript=", subscript, ", sub2=", sub2, ", sub3=", sub3, ", value=", ^Book(subscript,sub2,sub3)
           else {
             if moresub2=1 {
                     write !, "subscript=", subscript, ", sub2=", sub2, ", value=", ^Book(subscript,sub2)
      else {
      if moresub=1 {
      write !, "subscript=", subscript, ", value=", ^Book(subscript)

Hope this helps!

The 31-character limitation is there in 2018 (I'm using 2017 for this demonstration) - although anything longer doesn't technically error out, only the first 31 characters are recognized.

A quick demo I pulled from a test server:

NAME>s ^HH.LookupLabResultsToPhysiciansD(0)="fluffy"
NAME>zw ^HH.LookupLabResultsToPhysiciansD
NAME>s ^HH.LookupLabResultsToPhysiciansDoTryToDemonstrateLongGlobalNames(0)="More Fluffy"
NAME>zw ^HH.LookupLabResultsToPhysiciansDoNoFluffy
^HH.LookupLabResultsToPhysicians(0)="More Fluffy"

I underlined the characters that are 'ignored' - you can see on the ZWRITE command that the last 'D' (or anything after it) isn't displayed, and you can type all sorts of characters after that final 'D' and it still changes the 'base' 31-character global.

InterSystems probably put that check in because folks were using longer global names thinking all of the characters were significant, but some data was getting changed inadvertently.

Does that help?

Give the ^rINDEX global a look.

I made a QTEST routine in Studio, and saved it but did not compile it.


and then I executed this at the programmer prompt:

^rINDEX("QTEST","INT")=$lb("2021-08-06 13:21:58.061867",49)

I changed the routine a bit:


and I ZW'd the global again:

^rINDEX("QTEST","INT")=$lb("2021-08-06 13:24:50.38743",63)

It may be safe to assume that the underlined parameter is the length or number of bytes of storage required.

Now once I compile the routine in Studio, and ZW the global again, this is the output:

^rINDEX("QTEST","INT")=$lb("2021-08-06 13:24:50.38743",63)
^rINDEX("QTEST","OBJ")=$lb("2021-08-06 13:26:30",152)

Hope this helps!