0
    #!/bin/sh
    set -x
    
    
    #########################################################################
    #  This script will export a listing of all devices and where each device
    #  lives (GlobalCollection speaking).
    #  This list can then be used as a reference.
    #########################################################################
    #                          USE AT YOUR OWN RISK
    #########################################################################
    #
    #  ALTHOUGH THIS SCRIPT WORKED IN THE ORIGINAL ENVIRONMENT
    #  WHERE IT WAS WRITTEN IT IS NOT GUARANTEED TO WORK IN YOUR
    #  ENVIRONMENT.  THEREFORE, USE THIS SCRIPT AT YOUR OWN RISK.
    #  CA TECHNOLOGIES ASSUMES NO LIABILITY AS A RESULT OF RUNNING
    #  THIS SCRIPT.  THIS SCRIPT IS RUN AT THE SOLE DISGRESSION
    #  AND RISK OF  THE USER OR COMPANY RUNNING THIS SCRIPT.
    #                         HCL (c) 2023
    #
    #    WE SUGGEST THAT YOU BACKUP YOUR DATABASE BEFORE RUNNING ANY SCRIPT
    #    WHICH ACCESSES THE SSDB DATABASE.  IT WOULDN'T BE A BAD IDEA TO RUN
    #    A DDMDB BACKUP AS WELL.  YOU CAN'T HAVE TOO MANY BACKUPS :-)
    #
    ##########################################################################
    #
    #  You will need to verify the SPECROOT location and modify if necessary.
    #  You will also need to create a dir under /vnmsh called "MyScripts"
    #
    ######################          MAIN           ##########################
    
    host=$1
    SPECROOT=/es/Spectrum/DX-Spectrum   
    DATE=`date +%Y%m%d`
    CLISESSID=$$
    CLIMNAMEWIDTH=48
    CLIPATH=${SPECROOT}/vnmsh
    WORKPATH=${SPECROOT}/vnmsh/MyScripts         
    DEVICEGCPAIR=${WORKPATH}/Dev_and_GC_Pair.legacy  ## Old Server Location
    GC_NEWLIST=${WORKPATH}/GC_NewList.list          ## This file in on New SS
    NEWDEVICES=${WORKPATH}/NewEnvDevices.txt        ## This file is on New SS
    GCIMPORT=${WORKPATH}/Mh_IP_Mn_GCTopo.OUT
    NEWDEVWIP=${WORKPATH}/NewDevicesWithIPAdd.list 
    export SPECROOT DATE CLISESSID CLIMNAMEWIDTH CLIPATH WORKPATH 
    export DEVICEGCPAIR GC_NEWLIST NEWDEVICES GCIMPORT NEWDEVWIP DEVEXPORT
    
    #########      move old file to BAK      ###########
    
    if [ -a "${DEVICEGCPAIR}" ]
    then
    mv ${DEVICEGCPAIR} ${DEVICEGCPAIR}.BAK
    fi
    
    if [ -a "${GC_NEWLIST}" ]
    then
        mv ${GC_NEWLIST} ${GC_NEWLIST}.BAK
    fi
    
    if [ -a "${NEWDEVICES}" ]
    then
        mv ${NEWDEVICES} ${NEWDEVICES}.BAK
    fi
    
    ${CLIPATH}/connect $host
    
    read -p "Press Enter to continue...."
    
    #########  GETTING A LISTING OF ALL GLOBAL COLLECTIONS  #################
    
    ${CLIPATH}/show models mth=0x10474 |awk ' NR==1 {next;}; { print $1, $2} ' > ${GC_NEWLIST}
    
    ## GC_NEWLIST Format:  $1= 0x123456 (mh of GC) $2 = CollectionModelNameString, separated by ":"
    ## A sample line might look like this:  0x2003b6c Default Domain:GC_snmp:Jump Servers:VM Hosts
    ##                                      ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ##                                       MHandle  |>  starting here is the Collection list 
    ## NOTICE that the above list has only TWO columns.  The first Collection "Default Domain" just
    ## has a space in it, as well as other Collections in the list.   
    
    ##########   GETTING A LIST OF ALL DEVICES FROM THE SS   ################
    
    ${CLIPATH}/show devices |awk ' NR==1 {next;}; { print $1, $2} ' > ${NEWDEVICES}
    
    ## NEWDEVICES Format:  $1=<ModelHandle> (MH) $2=<Model Name> (MN)
        #### A sample line output is:  0x10027ef London_Core_Router_18
    ## I also need the IP address of the device, which is not provided in the previous step.
    ## I therefore am taking the file I just created and using it as an INPUT file to 
    ## using CLI, then creating a file with all three attributes.
    
    while read MH MN;
      do
        IPADD=`${CLIPATH}/show attributes attr=0x12d7f mh=${MH} | awk 'NR==1 {next;}; {print $3}'`
        echo ${MH}"|"${IPADD}"|"${MN} >> ${NEWDEVWIP}
      done < ${NEWDEVICES}
      
    ## The output of this will produce a file, each line containing the 
    ## Model Handle (MH), the IP ADDRESS and the Model Name (MN) of each 
    ## device in the database.  
    ## The MH is the unique identifier for that device.  All CLI activities 
    ## require the MH of the model (whether it's a device or not) to do some
    ## type of "thing" on it, whether it is to change an attribute, like the 
    ## Name of the device, or other.
    
    while read NEWMH NEWIPADD NEWMN;
     do
      cat ${DEVICEGCPAIR} |awk '/${NEWIPADD}/ && /${NEWMN}/'          
      GCLEG=`echo $LINE | awk '{print $3}' FS='|'`                         
      while read GCLINE; 
       do 
        GC01=`echo ${GCLINE} |awk '{print $1}' FS=':'`
        echo ${GC01}           # echo used in troubleshooting code.
        awk -v GC01= "$GC01"
        awk 'BEGIN{if(GC01=="");break 1;}'
        cat ${GC_NewList} |awk '/${GC01}/'|while read GCMH GCMN
         do
          ${CLIPATH}/create association rel=staticGlobalCollects lmh=${GCMH} rmh=${NEWIPADD};
         done 
        done < ${GCLEG}
      done < ${NEWDEVWIP}
    
    ${CLIPATH}/disconnect

################## DETAILS BELOW ###################

Hopefully I am reading the $NEWDEVWIP file, and populating the values of "NEWMH" "NEWIPADD" and "NEWMN" using the while read statement.

Now that I have the NEWMH, NEWIPADD, and NEWMN in tact I am catting the $DEVICEGCPAIR file, which is a file copied from another server with the following format: "MHandle"|"IP Add"|"ModelName"|"Collection String"
A sample line would look like: 0x10027ef|268.900.420.150|London_Core_Router_18|Default Domain:GC_snmp:Jump Servers:VM Hosts

I am finding the line in the $DEVICEGCPAIR file that has the same IP and Name as my "filter" and then pulling the Collection Name String.

Since the Collection Name String could have 0, 1, or even 40 Collections in that string (separated by a ":") I need to pull each Collection out and assign the string text to a variable, GC##, where ## could be 01 through 99 (although I've never seen devices being members of more than 20 or 30 Collections.

I then take each GC Name String and create an "association" using CLI. Once I do that the device model I just did the "create association" command with now lives in that Collection.

I check to see if the GC## has a value (because many devices do not live in any Collection) by using the awk 'BEGIN...' line. IF the GC## is blank or null, I need to exit out of that one loop and read in the next $DEVICEGCPAIR line.

In the above script I am only showing GC01, but I plan on copying/pasting this same code up to 30 times in case there are 30 Collections that a device is a member of. IF ANYONE KNOWS HOW BEST TO DO THAT I WOULD REALLY APPRECIATE IT.

I know there's a way to create a count++, but I have no idea how I would do that. So, until then :-) I am creating 30 individual GC## loops. That's why I wanted to know how to break out of the loop, because I don't want to go through all 30 iterations if I really only needed to go through 3.

DanL
  • 31
  • 5
  • 3
    in `bash` (not sure about other shells) `break -n` where `n` represents the number of loops/levels you want to break out of (default is `n=1`); if your shell does not support `break -n` you could set/clear a custom variable which you'd need to test at each level (though in thise case the first thing you'd need to do is get rid of the nested subshells since variable settings in a subshell are not seen by the parent shell) – markp-fuso May 23 '23 at 23:03
  • 2
    also, `awk '/${GC01}/'` will *not* have access to the unix variable `GC01` like you think it will; *hint:* run a web (or SO) search on how to pass shell varirables to `awk` – markp-fuso May 23 '23 at 23:11
  • 4
    Use `break n` (without `-`). Details: `help break` – Cyrus May 23 '23 at 23:15
  • 2
    It looks to me you can write the code only with either bash or awk without intermixing them. Embedding many short awk commands in a bash script makes the code less readable, less controllable and much less efficient. If you can provide your resource files and your desired output (or desired commands you want to invoke), we could be more help. – tshiono May 23 '23 at 23:16
  • 2
    typo .... `break n` ... *not* `break -n` .... ***what Cyrus said*** – markp-fuso May 23 '23 at 23:18
  • Thank you all for your input. Yes... I am not a coder. I have tried to piece together a number of bash scripts in my network management career... and I will be the first to admit that! I will include the entire script so you can see what I am doing. – DanL May 24 '23 at 01:05
  • If I use the "break n" or "break -n", will it take me out of my current loop and pass me to the loop from which I breaked out of? – DanL May 24 '23 at 01:06
  • `break` (or `break 1`) will break you out of the current loop; `break 2` will break you out of the current loop and the next/parent loop; `break 3` will break you out of the current loop, the next/parent loop and the next/grandparent loop; having said all that ... for your current code you won't be able to use `break n` because each of your subordinate loops are actually running in a subshell; you first need to eliminate the subshells ... – markp-fuso May 24 '23 at 13:14
  • to eliminate the subshell .... change `cat file | while read ...; do .... done` to `while read ...; do ... done < file` .... change `cat file | awk ... | while read ...; do ... done` to `while read ...; do ... done < <(awk '....' file)`; while editing/modifying your code also consider indenting successive blocks of loop code to make it easier to read the code – markp-fuso May 24 '23 at 13:16
  • Thank you!! I know I have lots to learn and I really appreciate this help!!! – DanL May 24 '23 at 13:32
  • So I looked up how to have awk use the variables... awk -v GC01="$GC01" – DanL May 24 '23 at 14:13
  • I changed the script to include what I think I learned in the comments section above. If it's not right, please let me know. THANKS IN ADVANCE!! I also added a complete logic sequence to my thinking in the "Details Below" section. I hope I've explained what I am trying to accomplish. – DanL May 24 '23 at 15:18
  • There's something very wrong in your code's logic if you think you need to break out of multiple levels deep. You should rethink what you're trying to do. – Ed Morton May 28 '23 at 21:19
  • You should copy/paste your code into http://shellcheck.net and fix the issues it tells you about. Also read [correct-bash-and-shell-script-variable-capitalization](https://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization) and then fix your variable names to avoid surprises and make your code easier to read. – Ed Morton May 28 '23 at 21:22
  • In your comments when you say `DISGRESSION` I think you mean `DISCRETION`. – Ed Morton May 28 '23 at 21:24

0 Answers0