AIX awk code fragment help

Clovertech Forums Read Only Archives Cloverleaf Operating Systems AIX awk code fragment help

  • Creator
    Topic
  • #49388
    Todd Lundstedt
    Participant

      I found a ksh script on my AIX cluster.  I can’t quite figure out what a portion of the script does.

      Code:

      IN=prod

      for FS in `lsvg -l ${IN}vg | awk ‘$2 == “jfs” {print $NF}’` ; do
        LV=`lsvg -l ${IN}vg | awk -v FLB=$FS ‘$NF == FLB {print $1}’`
        fuser -k /dev/$LV
        fuser -k /dev/$LV    
        fuser -k /dev/$LV    
        umount $FS
      done

      varyoffvg ${IN}vg

      What value is getting stuck into LV?  I can’t figure out what the awk statement is doing

      LV=`lsvg -l ${IN}vg | awk -v FLB=$FS ‘$NF == FLB {print $1}’`

      There are two filesystems in the prodvg, plus the jfslog.  When I run this command by itself, it returns nothing.  From what I can tell, a space (default field sep) is getting assigned to FLB, and awk would then return the $1 field from any line that contains a space?  And then 3x kill any processes attached to /dev/blank or /dev/newline or something like that?

      Obviously, the intent is to get all filesystems unmounted so the VG can get varied off, but I can’t quite figure out the design of this particular awk.

      Anyone got a clue what this is really trying to do (assuming my description above is wrong), or what the author’s thinking was for this?

    Viewing 5 reply threads
    • Author
      Replies
      • #61744
        David Barr
        Participant

          Code:

          for FS in `lsvg -l ${IN}vg | awk ‘$2 == “jfs” {print $NF}’` ; do

          Set FS to the mount point of each of the jfs logical volumes.

          Code:

          LV=`lsvg -l ${IN}vg | awk -v FLB=$FS ‘$NF == FLB {print $1}’`

          Set LV to the logical volume with a mount point that matches FS.

          FS probably stands for filesystem, not field separator.  In this script, it is a ksh variable, not an awk variable.

        • #61745
          Todd Wyndham
          Participant

            IN=prod

            for FS in `lsvg -l ${IN}vg | awk ‘$2 == “jfs” {print $NF}’` ; do

              LV=`lsvg -l ${IN}vg | awk -v FLB=$FS ‘$NF == FLB {print $1}’`

              fuser -k /dev/$LV

              fuser -k /dev/$LV

              fuser -k /dev/$LV

              umount $FS

            done

            varyoffvg ${IN}vg


            Example input data:

              $ lsvg -l prodvg

              prodvg:

              LV NAME             TYPE       LPs   PPs   PVs  LV STATE      MOUNT POINT

              sites2lv            jfs        257   514   2    open/syncd    /sites2

              loglv01             jfslog     1     1     1    closed/syncd  N/A

              apache2_lv          jfs        10    20    2    closed/syncd  /apache2

              eng2log01           jfslog     1     1     1    open/syncd    N/A


            `lsvg -l ${IN}vg | awk ‘$2 == “jfs” {print $NF}’` –>>

              awk defaults to field (column) separator of space

              $2 == “jfs” –>> test input field # 2 to string “jfs”, so it is looking at the TYPE column

              $NF –>> NF means the total number of fields found from the currently inputted line/record read in;

                       but placing a “$” sign in front of the variable NF means,

                       look at a given field in the inputted line/record,

                       thus in this example {print $NF} says to print the value of field # 7

            output from exampled lsvg input above:

              /sites2

              /apache2

            so the for loop becomes:

              for FS in /sites2 /apache2 ; do …


            LV=`lsvg -l ${IN}vg | awk -v FLB=$FS ‘$NF == FLB {print $1}’` –>>

              -v FLB=$FS –>> create the variable FLB with the value from the for loop; first time through, FLB equals /sites2

              ‘$NF == FLB {print $1}’ –>> for each inputted line, test the last input field of the currently read line/record with the variable FLB; if they are equal, print field number 1 of the current line/record;

                                           translated from first time in the for loop:

                                               ‘/sites2  == /sites2 {print sites2lv}’

                                               ‘N/A      == /sites2 {print loglv01}’

                                               ‘/apache2 == /sites2 {print apache2_lv}’

                                               ‘N/A      == /sites2 {print eng2log01}’


            so, when looping thru the for loop:

              FS = /sites2,  then LV = sites2lv

              FS = /apache2, then LV = apache2_lv

          • #61746
            Russ Ross
            Participant

              I was a bit intrigued by your newly discoverd script, too.

              I did some debug echos and slight modifications for my test box to determine the beahvior was what I initially suspected.

              The script is designed to varyoff a volume group after unmounting the filesystems that might be busy so do fuser -k to knock off any process accessing any of the file systems.

              I did wonder why there are 3 fuser -k commands.

              The top window in the attached screen shot shows my modified version of your script.

              The second window shows the output of running that script, which should help you answer your questions if you have not already figured it out.

              Russ Ross
              RussRoss318@gmail.com

            • #61747
              Russ Ross
              Participant

                Oh, I forgot to mention one other thing.

                I commneted out the meat of the script.

                If I wanted to really run the script I would need to be root.

                Only a system admin should be running a script like this with the intent of doing system maintenance of some kind.

                Russ Ross
                RussRoss318@gmail.com

              • #61748
                Todd Lundstedt
                Participant

                  Thanks all.

                  Monday, after my co-worker came back, we both looked at the script, and the FS confusion finally cleared when I realized the FS I was looking at was a variable (outside awk’s tick marks) of the Filesystem, and not the Field Sep…. so we finally understood it all.  We knew it was trying to unmount the filesystems, but the FS just confused me.  I am gonna find that original programmer and beat him for using an awk default variable so close to an awk command.  I have since changed the FS to FSYS.  That will make sure I don’t make the same mistake in 2.5 years the next time I see this script.

                  And to address Russ’ concern about the kill x3… that’s just that programmer being his typical overly-thorough self.

                  “I just want to make darn sure those processes are dead dead, and not just normal dead!”

                  Thanks again for the replies!

                  Todd

                • #61749
                  Tom Boyd
                  Participant

                    The reason for the 3 fuser commands is that once the first one is started, it will not know to kill any processes that spawn while it is running.

                Viewing 5 reply threads
                • The forum ‘Operating Systems’ is closed to new topics and replies.