LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Desktop (https://www.linuxquestions.org/questions/linux-desktop-74/)
-   -   add all network printers found via snmp call (https://www.linuxquestions.org/questions/linux-desktop-74/add-all-network-printers-found-via-snmp-call-4175462113/)

masonje 05-15-2013 11:20 AM

add all network printers found via snmp call
 
I have a task to add all the network printers found on a local LAN segment on our Linux thin clients. I think I have some of the fundamentals down on how to find them via an snmp discovery, and I now some of the basics on how to add a cups printer (not in the code snippit), but the thing I'm stuck on is how to get the information split up into usable chunks.

Here is the basic code for the discovery:

Code:

#!/bin/bash

tfile=/tmp/snmp.log
[ -f $tfile ] && rm $tfile

/usr/lib/cups/backend/snmp 2>&1 | tee $tfile

while read line         
do
        #echo "line - ${line}"
        typ=$(echo $line | awk '{ print $1 }')
        socket=$(echo $line | awk '{ print $2 }')
        if [ "$typ" = "network" ]
        then
                echo "Adding network printer $socket"
        else
                echo "skipping: $line"
        fi
done < $tfile

The resulting code will come back with a temp file like this:
network socket://192.168.24.12 "Canon iR5070 35.05" "Canon iR5070 35.05" "" "description x"
network socket://192.168.24.13 "Canon iR3570 35.06" "Canon iR3570 35.06" "" "description y"
network socket://192.168.24.15 "Canon iR5070 37.01" "Canon iR5070 37.01" "" ""
network socket://192.168.24.16 "Canon iR5070 37.01" "Canon iR5070 37.01" "" "Location x"


So here is my question. How to do I split each line into the usable chucks. I'm thinking a regular expression, but to be honest, sometimes those blow my mind on how to set them up. I'm thinking I (for example) in line:
network socket://192.168.24.12 "Canon iR5070 35.05" "Canon iR5070 35.05" "" "description x"

...I would need to remove the "network socket://192.168.24.12" so I'm just left with:
"Canon iR5070 35.05" "Canon iR5070 35.05" "" "description x"

...then split each field into variables so I can use them in the lpadmin command later:
var1="Canon iR5070 35.05"
var2="Canon iR5070 35.05"
var3=""
var4="description x"

Anyone know how I would accomplish this?

Habitual 05-15-2013 12:09 PM

Mad props on the discovery. ;) You are wise.
RE is the way to "go", but I lack the .fu myself, however, one possible solution could be...
Code:

cut -d\" -f2 x
or
Code:

cut -d\" -f2- x
but I got varying unsanitized output.YMMV.

where x has ...
Code:

network socket://192.168.24.12 "Canon iR5070 35.05" "Canon iR5070 35.05" "" "description x"
network socket://192.168.24.13 "Canon iR3570 35.06" "Canon iR3570 35.06" "" "description y"
network socket://192.168.24.15 "Canon iR5070 37.01" "Canon iR5070 37.01" "" ""
network socket://192.168.24.16 "Canon iR5070 37.01" "Canon iR5070 37.01" "" "Location x"

HTH.

masonje 05-15-2013 12:21 PM

Thanks Habitual. For what it's worth, this is what I have so far. I asked a co-worker and this was the method he suggested. That said, I have a bunch more work to figure out on dealing with cups drivers. I'll post the final code when I'm done.

Code:

#!/bin/bash

#~ set -x

tfile=/tmp/snmp.log
[ -f $tfile ] && rm $tfile

/usr/lib/cups/backend/snmp 2>&1 | tee $tfile

while read line         
do
        #echo "line - ${line}"
        typ=$(echo $line | awk '{ print $1 }')
        socket=$(echo $line | awk '{ print $2 }')
        if [ "$typ" = "network" ]
        then
                echo "Adding network printer $socket"
                newLine=$(echo $line | sed 's/^network[^\"]*\"//')
                v1=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $1 }')
                v2=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $2 }')
                v3=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $3 }')
                v4=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $4 }' | sed 's/\"//g')
                lpinfo --make-and-model "$v1" -m
        else
                echo "skipping: $line"
        fi
done < $tfile


Habitual 05-15-2013 12:28 PM

Quote:

Originally Posted by masonje (Post 4951876)
I'll post the final code when I'm done.

Subscribed with Interest...

masonje 05-16-2013 04:06 PM

getting very warm
 
Well the script is getting closer. Haven't decided on if I want to flat out install all the drivers we will need on the device, or figure out a creative way to do that.

Only thing I haven't quite figured out is how to deal with printers that come back with snmp names like "Lexmark Lexmark E360dn", when if I was to query for just "Lexmark E360dn", I find a driver. I REEEEELY don't want to have to come up with a case statement looking for known stupid returned names.

You can add your own log_msg log sub. We actually have an "include" that is sort of proprietary.

Code:

#!/bin/bash

#~ set -x

function log_msg(){
        echo  "$1 - $2"
        #~ return $TRUE
}


LOG="/tmp/printerInstall.log"

tnDriver=/tmp/noDriver.txt
tfile=/tmp/snmp.log
tdriver=/tmp/drivers.log
[ -f $tfile ] && rm -f $tfile
[ -f $tnDriver ] && rm -f $tnDriver

/usr/lib/cups/backend/snmp 2>&1 | tee $tfile

while read line         
do
        log_msg Info "--------------------------------------------------------------" true
        #echo "line - ${line}"
        typ=$(echo $line | awk '{ print $1 }')
        socket=$(echo $line | awk '{ print $2 }')
        if [ "$typ" = "network" ]
        then
                log_msg Info "Adding network printer $line" true
                newLine=$(echo $line | sed 's/^network[^\"]*\"//')
                v1=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $1 }')
                v2=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $2 }')
                v3=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $3 }')
                v4=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $4 }' | sed 's/\"//g')
               
                [ -f $tdriver ] && rm -f $tdriver
                lpinfo --make-and-model "$v1" -m 2>&1 | tee $tdriver
                dvr=$(lpinfo --make-and-model "$v1" -m)
               
                if [ 1 -ne $(cat $tdriver  | wc -c) ]
                then
                        log_msg Info "Drivers found" true
                       
                        if [ 0 -ne $(cat $tdriver | grep -E -w 'drv|foomatic|ppd.gz' | wc -c) ]
                        then
                                driver=""
                                while read dline
                                do
                                        driverTest=$(echo $dline | awk '{ print $1 }')
                                        #~ echo $driverTest
                                        #~ echo "-- ${driverTest:0:4}"
                                        if [ "${driverTest:0:4}" -a "drv:" ]
                                        then
                                                log_msg Info "Found driver: $driverTest" true
                                                driver=$(echo $driverTest)
                                        fi
                                        #~ echo "-- ${driverTest:0:4}"
                                        if [ "${driverTest:0:4}" -a "lsb\/" ]
                                        then
                                                log_msg Info "Found driver: $driverTest" true
                                                driver=$(echo $driverTest)
                                        fi
                                        #~ echo "-- ${driverTest:0:9}"
                                        if [ "${driverTest:0:9}" -a "foomatic:" ]
                                        then
                                                log_msg Info "Found driver: $driverTest" true
                                                driver=$(echo $driverTest)
                                        fi
                                done < $tdriver
                                #~ exit
                               
                                #setup label
                                if [ -z "$v4" ]
                                then
                                        label=$(echo $v1 | sed 's/\ //g')
                                        desc=" "
                                else
                                        label=$(echo $v1 | sed 's/\ //g')-$(echo $v4 | sed 's/\ //g')
                                        desc=" -L \"$v4\" "
                                fi
                               
                                if [ $(echo ${#driver}) -gt 0 ]
                                then
                                        log_msg Info "Run command: lpadmin -E -p $label -v $socket -m "$driver"$desc-E" true
                                        lpadmin -E -p $label -v $socket -m "$driver"$desc-E
                                        ret=$?
                                        if [ $ret -eq 0 ]
                                        then
                                                lpadmin -d $label
                                                ret=$?
                                                if [ $ret -eq 0 ]
                                                then
                                                        log_msg Info "Default printer: $label" true
                                                else
                                                        log_msg Error "** failed to set printer as default: $ret" true
                                                fi
                                        else
                                                log_msg Error "** failed to add printer: $ret" true
                                        fi
                                else
                                        log_msg Error "** No proper drivers found for printer" true
                                        echo $v1 >> $tnDriver
                                fi
                               
                        else
                                log_msg Warning "No PPD driver found" true
                                echo $v1 >> $tnDriver
                        fi
                else
                        log_msg Info "Drivers NOT found for: $v1" true
                        echo $v1 >> $tnDriver
                fi
        else
                log_msg Info "skipping: $line" true
               
        fi
done < $tfile

log_msg Info "Script complete" true


masonje 05-22-2013 03:20 PM

final
 
Just got done putting some finishing touches on this. I had to run another script to sort of gather an inventory at all our sites so I knew how to deal with some of the odd-ball returns I was getting from the snmp call. Hope this helps someone else!

Code:

#!/bin/bash

#~ set -x

function log_msg(){
        echo  "$1 - $2"
}

function InstallPrinter(){
        #~ log_msg Info "Starting printer install" true
       
        fSocket=$1
        fLabel=$2
        fDriver=$3
        fDesc=$4
       
        log_msg Info "Label: $fLabel" true
        log_msg Info "Driver: $fDriver" true
        log_msg Info "Description: $fDesc" true
       
        #remove
        lpadmin -x $fLabel
        log_msg Info "Remove prevous printer: $?" true
       
        if [ $(echo ${#fDriver}) -gt 0 ]
        then
                driverUsed="-m ${fDriver} "
        else
                driverUsed=""
                log_msg Info "** Using CUPS default driver" true
        fi
       
        descUsed=""
        if [ $(echo ${#fDesc}) -gt 0 ]
        then
                descUsed=" -L $(echo ${fDesc} | sed 's/\ /\-/g')"
        fi
       
        lpadminCmd="-E -p ${fLabel} -v ${fSocket}:9100 ${driverUsed} ${descUsed} -E"
        log_msg Info "Comand: lpadmin $lpadminCmd" true
        lpadmin $lpadminCmd
       
        ret=$?
        if [ $ret -eq 0 ]
        then
                lpadmin -d $label
                ret=$?
                if [ $ret -eq 0 ]
                then
                        log_msg Info "Default printer: $fLabel" true
                        RETURN=0
                else
                        log_msg Error "** failed to set printer as default: $ret" true
                        RETURN=1
                fi
        else
                log_msg Error "** failed to add printer: $ret" true
                RETURN=1
        fi
       
        #~ log_msg Info "Exit printer install: $RETURN" true
        return $RETURN
}


tnDriver=/tmp/noDriver.txt
tfile=/tmp/snmp.log
tdriver=/tmp/drivers.log
[ -f $tfile ] && rm -f $tfile
[ -f $tnDriver ] && rm -f $tnDriver

#discover all network snmp printers
/usr/lib/cups/backend/snmp 2>&1 | tee $tfile

while read line         
do
        log_msg Info "--------------------------------------------------------------" true
        #echo "line - ${line}"
        typ=$(echo $line | awk '{ print $1 }')
        socket=$(echo $line | awk '{ print $2 }')
        if [ "$typ" = "network" ]
        then
                driver=""
                dvr=""
                driverTest=""
                driverUsed=""
               
                log_msg Info "Adding network printer $line" true
                newLine=$(echo $line | sed 's/^network[^\"]*\"//')
                v1=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $1 }')
                v2=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $2 }')
                v3=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $3 }')
                v4=$(echo $newLine | awk 'BEGIN { FS="\" \"" } { print $4 }' | sed 's/\"//g')
               
                #printer name cleanup
                #--------------------------------------------------------------------------------------------------------------------------
                if [ "$v1" == "Unknown" ]
                then
                        log_msg Warning "Printer label \"Unknown\". Using $v2" true
                        v1=$v2
                fi
               
                v1=$(echo $v1 | sed 's/Lexmark\ Lexmark/Lexmark/g')
                v1=$(echo $v1 | sed 's/Lexmark\ \ Lexmark/Lexmark/g')
                if [ "${v1:0:5}" == "Canon" ]
                then
                        #~ log_msg Info "Current Canon model: $v1" true
                        v1=$(echo $v1 | sed 's/[^\n][^\n]\.[^\n][^\n]$//g')
                        v1=$(echo $v1 | sed 's/[^\n]\.[^\n]$//g')
                        #~ log_msg Info "Updated Canon model: $v1" true
                fi
                if [ $(echo "${v1}" | grep -E -w -i 'optra' | wc -c)  -gt 0 ]
                        then
                        v1="Lexmark Optra $(echo "$v1" | awk '{ print $3 }')"
                fi
                if [ "${v1:0:9}" == "Lexmark T" ]
                then
                        v1="Lexmark $(echo "$v1" | awk '{ print $2 }')"
                fi
                #--------------------------------------------------------------------------------------------------------------------------
                #printer name cleanup
               
                #setup printer name
                if [ -z "$v4" ]
                then
                        label=$(echo $v1 | sed 's/\ //g')
                        desc=""
                else
                        label=$(echo $v1 | sed 's/\ //g')-$(echo $v4 | sed 's/\ //g')
                        desc=$v4
                fi
               
                log_msg Info "Searching driver set for: $v1" true
                [ -f $tdriver ] && rm -f $tdriver
                lpinfo --make-and-model "$v1" -m 2>&1 | tee $tdriver
               
                #Check to see if the device has drivers for this printer
                if [ "$(cat $tdriver  | wc -c)"  -gt "31" ]
                then
                        log_msg Info "Drivers found" true
                       
                        #drv|foomatic|ppd.gz
                        if [ 0 -ne $(cat $tdriver | grep -E -w 'drv|foomatic|ppd' | wc -c) ]
                        then
                                driver=""
                                fInstall=1
                                while read dline
                                do
                                        driver=""
                                        driverTest=$(echo $dline | awk '{ print $1 }')
                                        #~ echo "-- $driverTest"
                                       
                                        #~ echo "-- ${driverTest:0:4}"
                                        if [ "${driverTest:0:4}" == "drv:" ]
                                        then
                                                log_msg Info "Found driver (drv:): $driverTest" true
                                                driver=$(echo $driverTest)
                                        #~ else
                                                #~ echo "not drv\:"
                                        fi
                               
                                        #~ echo "-- ${driverTest:0:9}"
                                        if [ "${driverTest:0:9}" == "foomatic:" ]
                                        then
                                                log_msg Info "Found driver (foomatic:): $driverTest" true
                                                driver=$(echo $driverTest)
                                        #~ else
                                                #~ echo "not foomatic:"
                                        fi
                                       
                                        #~ echo "-- ${driverTest:0:3}"
                                        if [ "${driverTest:0:3}" == "lsb" ]
                                        then
                                                log_msg Info "Found driver (lsb): $driverTest" true
                                                driver=$(echo $driverTest)
                                        #~ else
                                                #~ echo "not lsb:"
                                        fi
                                       
                                        if [ $fInstall -gt 0 ]
                                        then
                                                if [ $(echo ${#driver}) -gt 0 ]
                                                then
                                                        InstallPrinter  $socket $label "$driver" "${desc}"
                                                        fInstall=$?
                                                else
                                                        log_msg Info "** Driver found not to be proper: $driverTest" true
                                                fi
                                        else
                                                log_msg Info "Proper driver already found, skipping: $driverTest" true
                                        fi
                                        echo "--------------------------"
                                       
                                done < $tdriver
                        else
                                log_msg Warning "** No drv|foomatic|ppd.gz driver found" true
                                #~ echo $v1 >> $tnDriver
                        fi
                       
                        #~ if [ 0 -ne $fInstall ]
                        #~ then
                                #~ driver=""
                                #~ while read dline
                                #~ do
                                        #~ if [ $? -ne 0 ]
                                        #~ then
                                                #~ driverTest=$(echo $dline | awk '{ print $1 }')
                                                #~ InstallPrinter  $socket $label $driverTest "${desc}"
                                        #~ else
                                                #~ log_msg Info "Skip driver $driverTest" true
                                        #~ fi
                                #~ done < $tdriver
                        #~ else
                                #~ log_msg Info "Install complete: $label" true
                                echo $v1 >> $tnDriver
                        #~ fi
                else
                        log_msg Warning "Drivers NOT found for: $v1" true
                        echo $v1 >> $tnDriver
                fi
        else
                log_msg Info "skipping: $line" true
               
        fi
done < $tfile

log_msg Info "Script complete" true



All times are GMT -5. The time now is 07:28 AM.