Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
System Updater Script
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
cpman
n00b
n00b


Joined: 02 Aug 2013
Posts: 18

PostPosted: Sun Sep 14, 2014 5:46 pm    Post subject: System Updater Script Reply with quote

Hello everyone!
Recently, I wrote a script that can be used to keep your Gentoo system up to date.
I know that it is not hard to do it manually, but this script is a way to update and maintain your system with a single command.
It is just to save you from typing.
You can specify what to run with options on the command line.
You can get the script here. (On pastebin)
Hope you find it useful!

NOTE: This does require you to be present to perform multiple steps. This is so that you read the output of emerge, and know what other commands you need to run. (For instance, you may have to update configs, which can be done by passing "-C" to this script, or by running dispatch-conf.)
-cpman
Back to top
View user's profile Send private message
NeddySeagoon
Administrator
Administrator


Joined: 05 Jul 2003
Posts: 33579
Location: 56N 3W

PostPosted: Sun Sep 14, 2014 7:40 pm    Post subject: Reply with quote

cpman,

pastebin won't live forever - you can post your script here between code tags.

What about perlcleaner and python-updater when you get new versons of perl and/or python?
You need to detect them to know.
_________________
Regards,

NeddySeagoon

Computer users fall into two groups:-
those that do backups
those that have never had a hard drive fail.
Back to top
View user's profile Send private message
cpman
n00b
n00b


Joined: 02 Aug 2013
Posts: 18

PostPosted: Sun Sep 14, 2014 8:03 pm    Post subject: Reply with quote

Ok. I'll work on adding python-updater and perlcleaner.
For now, here is the script in code tags:

Code:

#!/bin/bash

# Copyright (C) 2014 Alexander Mohn <pogrmman+dev@gmail.com>
# Permission is hereby granted, free of charge, to any person obtaining a copy of this script to use it without restriction,
# including without limitation of the rights to use, copy, modify, merge, publish, distribute, and/or sublicense this script
# subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of this
# script.
# THIS SCRIPT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THIS SCRIPT.

# This script provides a way to update and maintain your Gentoo system
# with a single command.


####### Functions #######

# This updates the portage tree.
function sync
{
   read -p "Press [Enter] to update the portage tree..."
   sudo emerge --sync
}

# This updates the system.
function update
{
   read -p "Press [Enter] key to begin updating system..."
   sudo emerge --ask --update --deep --with-bdeps=y --newuse @world
}

# This changes any configuration files that must be updated.
function config
{
   read -p "Press [Enter] key to change configuration files..."
   sudo dispatch-conf
}
# This checks for broken packages.
function pkg_check
{
   read -p "Press [Enter] key to check for broken packages..."
   sudo revdep-rebuild -p
}

# This rebuilds broken packages.
function pkg_rebuild
{
   read -p "Press [Enter] key to rebuild broken packages..."
   sudo revdep-rebuild
}

# This removes obsolete packages.
function clean
{
   read -p "Press [Enter] key to remove obsolete packages..."
   sudo emerge --ask --depclean --with-bdeps=y
}

# This prints introductory text.
function intro
{
   cat <<- _INTRO_
   Welcome to the system updater.
   You may be asked to enter your password several times during the process.
   If you do not have sudo privilages for emerge, revdep-rebuild,
   and dispatch-conf, this script may fail.
   _INTRO_
}

# If no options are specified.
function noopts
{
   cat <<- _DESC_
   This script helps to keep your Gentoo system up to date.
   You must specify at least one option.
   USAGE: update [-option1] [-option2] [-option3] [-option4] [-option5] [-option6]

           -S Sync the portage tree.
           -U Update the system.
           -C Change config files.
           -P Check for broken packages.
           -p Rebuild broken packages.
           -D Remove obsolete packages and dependenicies.
           -h Display this help text.
   
   WARNING: Options will be parsed in the order in which they are given.
   It is generally wise to use -S before -U, -U before -D, and -D before -p.
   _DESC_
}

####### End of Function Declarations #######

####### Main #######

if [ "$1" = "" ]; then                # Checks to see if any options are specified.
   noopts                           # If not, it displays usage.
else
   if [ "$1" = "-h" ]; then         # Checks to see if -h is specified.
      noopts                        # If it is, it displays usage.
   else
      intro                        # Display introductory text.
      while [ "$1" != "" ]; do      # Option parser.
         case $1 in
            -h ) noopts ;;
            -S ) sync ;;
            -U ) update ;;
            -C ) config ;;
            -P ) pkg_check ;;
            -p ) pkg_rebuild ;;
            -D ) clean ;;
         esac
         shift
      done                     # End of option parser.
      echo "Done updating system!"
   fi
fi
exit 0

####### End #######   

Back to top
View user's profile Send private message
cpman
n00b
n00b


Joined: 02 Aug 2013
Posts: 18

PostPosted: Mon Sep 15, 2014 1:18 am    Post subject: Reply with quote

As far as I know, this version SHOULD detect major Python updates, and run python-updater.
It is a bit messy, and uses a makes a subdir in /tmp, but it cleans up after itself.
Unfortunately, there has not been a major python update to test it with since I wrote this modified version.
I'm still working on detecting Perl updates.
Anyway, here is the modified version:
Code:

#!/bin/bash

# Copyright (C) 2014 Alexander Mohn <pogrmman+dev@gmail.com>
# Permission is hereby granted, free of charge, to any person obtaining a copy of this script to use it without restriction,
# including without limitation of the rights to use, copy, modify, merge, publish, distribute, and/or sublicense this script
# subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of this
# script.
# THIS SCRIPT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THIS SCRIPT.

# This script provides a way to update and maintain your Gentoo system
# with a single command.


####### Functions #######

# This updates the portage tree.
function sync
{
   read -p "Press [Enter] to update the portage tree..."
   sudo emerge --sync
}

# This logs the old python version.
function python_old
{
   mkdir /tmp/update
   eselect python list > /tmp/update/python_old.lst                           # Makes a list of old python versions.
   awk '{print $2}' < /tmp/update/python_old.lst > /tmp/update/python_old            # Extracts version names.
   python_old=($(cat /tmp/update/python_old))
   pyv2_old=${python_old[1]}
   pyv3_old=${python_old[2]}
   echo $pyv2_old > /tmp/update/pyv2_old
   echo $pyv3_old > /tmp/update/pyv3_old
   cut -c 9 /tmp/update/pyv2_old > /tmp/update/v2_old                           # Converts version names into numbers.
   cut -c 9 /tmp/update/pyv3_old > /tmp/update/v3_old
   pyv2_old=($(cat /tmp/update/v2_old))
   pyv3_old=($(cat /tmp/update/v3_old))
}

# This logs the new python version.
function python_new
{
   eselect python list > /tmp/update/python.lst                                 # Lists new versions of python.   
   awk '{print $2}' < /tmp/update/python.lst > /tmp/update/python                  # Extracts the version names.
   py=($(cat /tmp/update/python))
   pyv2=${py[1]}
   pyv3=${py[2]}
   echo $pyv2 > /tmp/update/pyv2
   echo $pyv3 > /tmp/update/pyv3
   cut -c 9 /tmp/update/pyv2 > /tmp/update/v2                                 # Converts the version names into numbers.
   cut -c 9 /tmp/update/pyv3 > /tmp/update/v3
   pyv2=($(cat /tmp/update/v2))
   pyv3=($(cat /tmp/update/v3))
}

# This updates the system.
function update
{
   read -p "Press [Enter] key to begin updating system..."
   python_old
   sudo emerge --ask --update --deep --with-bdeps=y --newuse @world
   python_new
   if [ "$pyv2_old" != "$pyv2" ]; then
      read -p "Press [Enter] key to fix files broken by Python 2.x update..."
      sudo python-updater
   fi
   if [ "$pyv3_old" != "$pyv3" ]; then
      read -p "Press [Enter] key to fix files broken by Python 3.x update..."
      sudo python-updater
   fi
}

# This changes any configuration files that must be updated.
function config
{
   read -p "Press [Enter] key to change configuration files..."
   sudo dispatch-conf
}
# This checks for broken packages.
function pkg_check
{
   read -p "Press [Enter] key to check for broken packages..."
   sudo revdep-rebuild -p
}

# This rebuilds broken packages.
function pkg_rebuild
{
   read -p "Press [Enter] key to rebuild broken packages..."
   sudo revdep-rebuild
}

# This removes obsolete packages.
function clean
{
   read -p "Press [Enter] key to remove obsolete packages..."
   sudo emerge --ask --depclean --with-bdeps=y
}

# This prints introductory text.
function intro
{
   cat <<- _INTRO_
   Welcome to the system updater.
   You may be asked to enter your password several times during the process.
   If you do not have sudo privilages for emerge, revdep-rebuild, dispatch-conf,
   python-updater, and perl-cleaner this script may fail.
   _INTRO_
}

# If no options are specified.
function noopts
{
   cat <<- _DESC_
   This script helps to keep your Gentoo system up to date.
   You must specify at least one option.
   USAGE: update [-option1] [-option2] [-option3] [-option4] [-option5] [-option6]

           -S Sync the portage tree.
           -U Update the system.
           -C Change config files.
           -P Check for broken packages.
           -p Rebuild broken packages.
           -D Remove obsolete packages and dependenicies.
           -h Display this help text.
   
   WARNING: Options will be parsed in the order in which they are given.
   It is generally wise to use -S before -U, -U before -D, and -D before -p.
   _DESC_
}

####### End of Function Declarations #######

####### Main #######

if [ "$1" = "" ]; then                                                    # Checks to see if any options are specified.
   noopts                                                            # If not, it displays usage.
else
   if [ "$1" = "-h" ]; then                                             # Checks to see if -h is specified.
      noopts                                                         # If it is, it displays usage.
   else            
      intro                                                         # Display introductory text.
      while [ "$1" != "" ]; do                                          # Option parser.
         case $1 in
            -h ) noopts ;;
            -S ) sync ;;
            -U ) update ;;
            -C ) config ;;
            -P ) pkg_check ;;
            -p ) pkg_rebuild ;;
            -D ) clean ;;
         esac
         shift
      done                                                         # End of option parser.
      echo "Done updating system!"
   fi
fi
rm -r /tmp/update
exit 0

####### End #######   
Back to top
View user's profile Send private message
steveL
Advocate
Advocate


Joined: 13 Sep 2006
Posts: 3763
Location: The Peanut Gallery

PostPosted: Thu Sep 18, 2014 1:11 pm    Post subject: Reply with quote

You might like update then; it started out the same way, as an exercise to learn bash, back when portage was serial, and always spewed loads of crap to the console (and had no --keep-going, in fact.) It does all the things talked about in this thread, plus a whole lot more, though in general, you just use update to do the standard world upgrade, or update -s to sync first.

Patches and ideas are ofc welcome :) (though use the git version if you do try it, as all of us do, since the ebuild is over a year out of date; it'll get updated once --toolchain is fully functional. Oh, and I'm well aware it should be split into separate files; again that's waiting, though the reason it's so long without split apart from libfile, is as I was somewhat perversely trying to make bash fall over, back when I was on a 32-bit system. It never did.)

I highly recommend #bash on IRC: chat.freenode.net: they'll teach you an awful lot about Unix portability, as well as bash scripting (and they can teach you POSIX sh too, if you ask for that upfront.)
Back to top
View user's profile Send private message
brendlefly62
n00b
n00b


Joined: 19 Dec 2009
Posts: 29

PostPosted: Mon Sep 29, 2014 1:12 am    Post subject: Reply with quote

Here's mine -- same sort of drill... Note that it has useful default values, but it looks for update-sequence.conf in several places. It checks the timestamp of your last source sync to determine if it needs to emerge --sync first... It also stores a status variable so that you can enjoy its "resume" option... in case you need to pop out and ... say update your kernel or gcc or something like that... I think it still has a


Code:
#!/bin/bash
# /usr/local/sbin/update-sequence
# Standardized Gentoo update sequence, implemented as interactive
#   script with "resume" functionality
# Author: --------------- 23 Jan 2011
# Rev 31 Dec 12 - ver 3.0 added package cleaning w/ eclean-pkg if applicable
# Rev 24 Feb 13 - ver 3.1 made "emerge --depclean" interactive by adding options "-av"
# Rev 21 Jul 13 - ver 3.2 removed lafilefixer and changed "revdep-rebuild -p" (obsoleted by portage improvements)
# Rev 9 Feb 14 - ver 4.0 added binary package support (for embedded, e.g. raspberryPi)
# Rev 2 Mar 14 - ver 4.1-4.2.2 bugfixes and improvement to check news, maintain configs, and add log entry
# Rev 22 Mar 14 - ver 4.2.3 bugfix for maintain configs
# Rev 11 May 14 - ver 4.2.4 bugfix for maintain /usr/share/config configs
# Rev 26 May 14 - ver 4.2.5 add aesthetics of prog name and build in each step
# Rev 27 Jul 14 - ver 4.2.6 bugfix (display $BUILD)
# Rev 17 Aug 14 - ver 4.3.0 added --exclude <atom> option
#
# Source the variable assignments made in update-sequence.conf (/etc/ overrides pwd)
#   This will supercede/modify the default assignments made below
CONF_DIR="defaults"
[[ -e update-sequence.conf ]] && . update-sequence.conf && CONF_DIR=$PWD"/update-sequence.conf"
[[ -e /etc/update-sequence.conf ]] && . /etc/update-sequence.conf && CONF_DIR="/etc/update-sequence.conf"

# User-defined variables - modify according to your system
# SCRIPT_DIR is the directory in which you have placed
#   this script and the show-elogs script
[ -z "$SCRIPT_DIR" ] && SCRIPT_DIR="/usr/local/sbin/"    # must end with '/'

# STATUS_FILE is the name of the status file
#   generated and used by this script.  Provide the complete pathname
[ -z "$STATUS_FILE" ] && \
    STATUS_FILE="/root/bin/update-sequence-status" || \
    STATUS_FILE=$STATUS_FILE

# SYNC_TS is the pathname of the file the timestamp of which will
#   be checked to determine how long it's been since the portage
#   tree was last sync'd
[ -z "$SYNC_TS" ] && SYNC_TS="/usr/portage/metadata/timestamp.chk"       # emerge --sync timestamp

# MAX_AGE is the maximum time in hours since last sync before this script
#   will automatically choose to emerge --sync
[ -z "$MAX_AGE" ] && MAX_AGE=24

# ELOG_DIR is the location of elog files
[ -z "$ELOG_DIR" ] && ELOG_DIR="/var/log/portage/elog/"

# --- Define local variables -----------------------------------
BUILD="4.3.0 (20140817)"

BOLDon="\033[1m"
GREENon="\033[32m"
YELLOWon="\033[33m"
REDon="\033[31m"
BLUEon="\033[36m"
BGon=$BOLDon$GREENon
BYon=$BOLDon$YELLOWon
BRon=$BOLDon$REDon
BBon=$BOLDon$BLUEon
Boff="\033[0m"
step=1
laststep=5
continue="y"
RESUME="no"
GO_AHEAD="no"
SYNC="no"
USEPKG="no"
USEPKGONLY="no"
GETBINPKG="no"
GETBINPKGONLY="no"
KEEPGOING="no"

ROOT_UID=0       # Only users with $UID 0 have root privileges

# Error message used by script
E_NOTROOT="Must be root to run this script."
E_BAD_ARGS="Improperly formatted command line argument."

# Array of messages used to announce each step
step_message[1]="update-sequence-"$BUILD" step 1 - Sync and Emerge Updates"
step_message[2]="update-sequence-"$BUILD" step 2 - Review news and Maintain Config Files"
step_message[3]="update-sequence-"$BUILD" step 3 - Review elogs"
step_message[4]="update-sequence-"$BUILD" step 4 - Handle Dependencies"
step_message[5]="update-sequence-"$BUILD" step 5 - Final Cleanup"
step_message[6]='update-sequence-'$BUILD' step 6 - Update Sequence Complete.  Enter "y" to exit'


# --- function blocks ------------------------------------------


sanity_check()
{
# veryfy the sanity of the combination of arguments on the command line
[ "$SYNC" = "yes" ] && [ "$RESUME" = "yes" ] && \
   E_message "Nonsensical option combination: sync and resume" && \
   useage && exit 1

[ "$SYNC" = "yes" ] && [ "$GO_AHEAD" = "yes" ] && \
   E_message "Dangerous option combination: sync and go_ahead" && \
   E_message "(you should never merge packages blindly, please check first)" && \
   useage && exit 1
}

process_command_line()
{
# process command line arguments (for now only -x/--exclude option can have an argument)
last=""
#message "processing command line with argument(s): [ ${*} ]"
for i in "$*"
do
  if [[ ! "$last" == "-x" ]]
  then
    process_argument $last $i
    last="arg"
  else  # last was not -x
    if [ ! "$last" == "arg" ]   # if last was not -x, but last was arg, just skip to the next opt on cmd line
    then                        # if last was not -x, and last was not arg, so process as normal option
      process_argument $i
      last="$i"
      [ "$last" == "--exclude" ] && message "recasting --exclude to -x" && last="-x"
    fi
  fi
done
sanity_check
}

process_argument()
{
EXCLUDE=""
#message "about to process argument: [ $* ]"
#message "1: [ $1 ], 2: [ $2 ]"
# process command line argument (must be one of the following)
[ ! -z "$1" ] && case "$1" in
    "-g" | "--getbinpkg"     ) GETBINPKG="yes" ;;
    "-G" | "--getbinpkgonly" ) GETBINPKGONLY="yes" ;;
    "-k" | "--usepkg"        ) USEPKG="yes" ;;
    "-K" | "--usepkgonly"    ) USEPKGONLY="yes" ;;
    "-r" | "--resume"        ) RESUME="yes" ;;
    "-s" | "--status"        ) status ; exit 0 ;;
    "-x" | "--exclude"       ) EXCLUDE="$2" ;;
    "-Y" | "--go-ahead"      ) GO_AHEAD="yes" ;;
    "-y" | "--sync"          ) SYNC="yes" ;;
    "-Z" | "--keep-going   " ) KEEPGOING="yes" ;;
    "-h" | "--help"          ) useage ; exit 0 ;;
    *                        ) process_compound_arg $1 ;;
esac

}

process_compound_arg()
{
# must begin with a single dash
[ ! "${1:0:1}" = "-" ] && E_message "${E_BAD_ARGS}" && useage && exit 1
# must not begin with two dashes (would have been picked in process_argument)
[ "${1:0:2}" = "--" ] && E_message "${E_BAD_ARGS}" && useage && exit 1
# strip leading dash(es)
myargs=${1##-}
# handle remaining characters in sequence
while [ -n "${myargs}" ]
do
    #handle first char
    case ${myargs:0:1} in
        "r") RESUME="yes" ;;
        "Y") GO_AHEAD="yes" ;;
        "y") SYNC="yes" ;;
        "k") USEPKG="yes" ;;
        "K") USEPKGONLY="yes" ;;
        "g") GETBINPKG="yes" ;;
        "G") GETBINPKGONLY="yes" ;;
        "Z") KEEPGOING="yes" ;;
        *  ) E_message "${E_BAD_ARGS}" && useage && exit 1
    esac
    #strip first char from myargs
    myargs=${myargs:1}
done

}

useage()
{
   echo -e $BGon"Useage: update-sequence [option]"$Boff
   echo -e " Command line options:"
   echo -e "  "$BBon"[-g | --getbinpkg]"$Boff"........use local and remote binary packages and ebuilds"
   echo -e "  "$BBon"[-G | --getbinpkgonly]"$Boff"....use local and remote binary packages only"
   echo -e "  "$BBon"[-k | --usepkg]"$Boff"...........use local binary packages and ebuilds"
   echo -e "  "$BBon"[-K | --usepkgonly]"$Boff".......use local binary packages only"
   echo -e "  "$BBon"[-r | --resume]"$Boff"...........resume update sequence at next step"
   echo -e "  "$BBon"[-s | --status]"$Boff"...........print next step in update sequence"
   echo -e "  "$BBon"[-x | --exclude <atom>]"$Boff"...exclude <atom> from emerge"
   echo -e "  "$BBon"[-y | --sync]"$Boff".............force emerge --sync"
   echo -e "  "$BBon"[-Y | --go-ahead]"$Boff".........automatically continue to next steps"
   echo -e "  "$BBon"[-Z | --keep-going]"$Boff".......on emerge failure, try to keep emerging other packages"
   echo -e "  "$BBon"[-h | --help]"$Boff".............print this text"
   echo
   echo -e "  "$BYon"Notes: "$Boff
   echo -e "  "$BYon" 1\)"$Boff" --status and --resume both identify the next step"
   echo -e "    \(which is the last successfully completed step + 1\)"
   echo -e "  "$BYon" 2\)"$Boff" --sync is set automatically if portage tree is older"
   echo -e "    than MAX_AGE \(set in update-sequence.conf\)"
   echo -e "  "$BYon" 3\)"$Boff" option\(s\) -[k|K|g|G] function as explained in gentoo binary package guide:"
   echo -e "    https://wiki.gentoo.org/wiki/Binary_package_guide"
   echo
}

status()
{
    read step < ${STATUS_FILE}
    echo "next step: ${step_message[${step}]}"
    echo
}

checkroot()
{
    # Run as root, of course.
    if [ "$UID" -ne "$ROOT_UID" ]
    then
        E_message "${E_NOTROOT}"
        echo
        exit 1
    fi
}

display_config()
{
message "Using configuration data below: "
echo "Configuration: "${CONF_DIR}
echo "SCRIPT_DIR: "${SCRIPT_DIR}
echo "STATUS_FILE: "${STATUS_FILE}
echo "SYNC_TS: "${SYNC_TS}
echo "MAX_AGE: "${MAX_AGE}
echo "SYNC: "${SYNC}
echo "RESUME: "${RESUME}
echo "GO_AHEAD: "${GO_AHEAD}
echo "USEPKG: "${USEPKG}
echo "USEPKGONLY: "${USEPKGONLY}
echo "GETBINPKG: "${GETBINPKG}
echo "GETBINPKGONLY: "${GETBINPKGONLY}
echo "KEEPGOING: "${KEEPGOING}
echo "EXCLUDE: "${EXCLUDE}
}

message()
{
    # echo a simply formatted message to the screen
    # arguments: string message
    # external variables: all other variables must be set in the shell calling $

    echo -e "${BGon}*${Boff} ${1}"
}

E_message()
{
    # echo a simply formatted error message to the screen
    # arguments: string message
    # external variables: all other variables must be set in the shell calling $

    echo -e "${BRon}*${Boff} ${1}"
}

separator()
{
    # echo a horizontal colored line with a simple title as a separator
    #   to facilitate separation of portions of the output of the boot process
    # arguments: string title for separator line
    # external variables: all other variables must be set in the shell calling $

    # determine the terminal width from output of coreutil infocmp
    termwidth=$(stty size | sed 's/[0-9]* *//')

    # start with three bold yellow dashes and a bar
    tst="$BYon---[$Boff"
    # modify termwidth to not count the escape sequences
    m_termwidth=`expr $termwidth + ${#BYon} + ${#Boff}`

    # after a space, include the message in bold light blue and add another spa$
    tst=`expr  $tst" "$BBon"$1"$Boff" "`
    # modify termwidth to not count the escape sequences
    m_termwidth=`expr $m_termwidth + ${#BBon} + ${#Boff}`

    # add a bar and more dashes in bold yellow until the terminal width is reac$
    tst="$tst$BYon]"
    # modify termwidth to not count the escape sequences
    m_termwidth=`expr $m_termwidth + ${#BYon}`

    while [ ${#tst} -lt $m_termwidth ]
    do
        tst="$tst-"
    done
    tst="$tst$Boff"

    echo
    echo -e $tst
}

check_timestamp()
{
    # compute age in hours of timestamp on file passed as argument
    # set $SYNC flag to "yes" if timestamp is older than $MAX_AGE allows
    SPM=60   # seconds per minute
    MPH=60   # minutes per hour
    agehours=$(( $(( $(date -u +%s) - $(date -u -r $1 +%s))) / $SPM / $MPH ))
    #if it's old, set SYNC flag
    message "Portage tree last sync'd $agehours hours ago"
    [ "$SYNC" = "yes" ] && \
        message "option: sync set by command line" || \
        message "option: sync not set by command line"
    if [ $agehours -gt $MAX_AGE ]
    then
        if [ "$GO_AHEAD" = "yes" ]
        then
            # sanity-check: unwise to go-ahead immediately after sync
            #  without checking what will be merged
            E_message "You selected option: go-ahead " && \
            E_message "but you also set MAX_AGE: $MAX_AGE hours in update-sequence.conf" && \
            E_message "The latter would cause this program to sync and then auto-emerge non-interactively" && \
            E_message "(you should never merge packages blindly, please check first)" && \
            useage && exit 1
        else
            SYNC="yes" && \
            message "emerge --sync required by MAX_AGE ($MAX_AGE hours) set in update-sequence.conf"
        fi
    else
        message "emerge --sync not required by MAX_AGE ($MAX_AGE hours) set in update-sequence.conf"
    fi
}

emerge_sync()
{
    # check to see if portage tree is up to date
    # if timestamp of last emerge --sync is old, do a new one
    check_timestamp "$SYNC_TS"
    [ "$SYNC" = "yes" ] && \
        message "Running emerge --sync... " && emerge --sync
    return 0
}

emerge_updates()
{
    # assemble the emerge option string and message
    OPTS1="uvDN"
    OPTS2=""
    MSG="emerging updates"
    if [ ! "${GO_AHEAD}" = "yes" ]
    then
        OPTS1="a"${OPTS1}
        MSG=${MSG}" interactively"
    else
        MSG=${MSG}" non-interactively"
    fi
    [ "${USEPKG}" = "yes" ] && OPTS1=${OPTS1}"k"
    [ "${USEPKGONLY}" = "yes" ] && OPTS1=${OPTS1}"K"
    [ "${GETBINPKG}" = "yes" ] && OPTS1=${OPTS1}"g"
    [ "${GETBINPKGONLY}" = "yes" ] && OPTS1=${OPTS1}"G"
    [ "${KEEPGOING}" = "yes" ] && OPTS2=${OPTS2}" --keep-going"
    [ ! -z "${EXCLUDE}" ] && OPTS2=${OPTS2}" --exclude "${EXCLUDE}

    MSG=${MSG}" [${BRon} emerge -"${OPTS1}" world ${OPTS2} ${Boff}] per command line options..."
    message "${MSG}"
    emerge -${OPTS1} world ${OPTS2} && return 0

    return 1
}

show_news()
{
    # display any news...
    message "The following news has been generated:"
    eselect news read new
    echo
}

maintain_config_files()
{
    # run dispatch-conf to maintain configs, if this is necessary
    # if the optional go-ahead flag is set, skip this (remind user later)
    if $( [[ -z "$(find /etc/ -iname '*._cfg***')" ]] && \
       [[ -z "$(find /usr/share/config/ -iname '*._mrg***')" ]] )
    then
        message "No config files need maintenance."
    else
        if [ ! "$GO_AHEAD" = "yes" ]     # note: use of the GO_AHEAD option will cause this step to be skipped
        then
            message "Launching dispatch-conf to maintain the following config files:"
            echo $(find /etc/ -iname '*._cfg***')
            dispatch-conf
        fi  # not go_ahead
    fi  # find/not-find
    echo
    return 0
}

showelogs()
{
    # run show-elogs script to apply important steps from emerge notes
    # if the optional go-ahead flag is set, skip this (remind user later)
    message "Running show-elogs -l | less ..." && [ "$GO_AHEAD" = "no" ] && ${SCRIPT_DIR}show-elogs -l | less && return 0 || return 1
}

handle_dependencies()
{
    message "Running emerge -av --depclean && revdep-rebuild -p ..." && \
      emerge -av --depclean && revdep-rebuild -p
    # recommend you run revdep-rebuild again if it had to
    #   emerge something to fix dependencies
    # TO DO: check if that's the case and ask this only if so

    [ "$GO_AHEAD" = "no" ] && \
    echo -en $BYon"would you like to run revdep-rebuild again, for action? (y/n) "$Boff && \
    read rerun && echo || \
    rerun="y"
    case $rerun in
        "y") revdep-rebuild && return 0 ;;
        *) return 0 ;;
    esac
}

final_cleanup()
{
    # clean un-needed package and distribution files, run localepurge
    [ -d "/usr/portage/packages" ] && message "Running eclean-pkg ..." && eclean-pkg
    message "Running eclean-dist -d ..." && eclean-dist -d && \
    message "Running localepurge ..." && localepurge && \
    return 0
}

ask_continue()
{
    # prompt to determine if or how to continue
    # y = continue to next step, n = stop now, g = go ahead through all remaining steps non-interactively
    continue="x"
    while [[ ! `echo ${continue:0:1} | sed 's/^[yngYNG]*//' | wc -c` -eq 1 ]]
    do
        echo -en $BGon"*"$Boff" continue to ${step_message[${step}]} (y), stop (n), or go ahead through (g)? [Y/n/g] :" && \
        read continue && echo
        # if the response is "g" then set the GO_AHEAD flag and continue; if null apply default (y)
        case ${continue:0:1} in
            "g" | "G" ) GO_AHEAD="yes" && continue="y" ;;
            ""        ) continue="y" ;;
            "y" | "Y" ) continue="y" ;;
        esac
    done

}

# --- start main script ---------------------------------------------------------

# display script kick-off separator
separator "update-sequence-${BUILD}"

# process command line to set and check sanity of option flags
message "Checking root UID... "&& checkroot

# display config variables from update-sequence.conf and option flags from command line
display_config

# if resuming, retrieve number of next step to be performed from status file
[ "$RESUME" = "yes" ] && read step < $STATUS_FILE

# proceed thru each step, as allowed to continue, until complete
while [ "$continue" = "y" ] && [ "$step" -le "$laststep" ]
do
    separator "${step_message[$step]}"
    case $step in
        "1") emerge_sync ;
             emerge_updates && echo -e $BGon"OK"$Boff  ;;
        "2") show_news ;
             maintain_config_files && echo -e $BGon"OK"$Boff ;;
        "3") showelogs && echo -e $BGon"OK"$Boff ;;
        "4") handle_dependencies && echo -e $BGon"OK"$Boff ;;
        "5") final_cleanup && echo -e $BGon"OK"$Boff ;;
    esac
    message "Successfully completed: ${step_message[${step}]}"
    let "step += 1"
    echo $step > $STATUS_FILE
    # determine whether or how to proceed to next step
    case $GO_AHEAD in
        "yes") continue="y" ;;
        "no")  ask_continue ;;
    esac
done

# if go-ahead flag was set, remind user
if [ "$GO_AHEAD" = "yes" ]
then
    message "You ran update sequence with option: go-ahead."
fi

# if go-ahead flag was set and new configs are pending, tell user
if [ "$GO_AHEAD" = "yes" ]
then
    if [[ ! -z "$(find /etc/ -iname '*._cfg***')" ]] || \
       [[ ! -z "$(find /usr/share/config/ -iname '*._mrg***')" ]]
    then
        E_message 'You have updated config files pending. You should run "dispatch-conf"'
        E_message "found the following pending config file updates:"
        echo $(find /etc/ -iname '*._cfg***')
    fi # found configs
fi  # go_ahead

# if go-ahead flag was set and new elogs resulted from updates, tell user
if [ "$GO_AHEAD" = "yes" ]
then
    for x in $(ls $ELOG_DIR | cut -d":" -f 3 | cut -d"-" -f 1 | sort -nu); do : ; done && \
    [ "$x" = "$(date -u +%Y%m%d)" ] && \
    E_message 'update-sequence produced new elogs.  You should run "show-elogs"'
fi

/usr/bin/logger -p cron.notice "update-sequence complete."
message "Logged and done.
"
exit 0


Code:
#/etc/update-sequence.conf
# Configuration file for standardized Gentoo update sequence,
# implemented as interactive script with "resume" functionality
# Author: ------------------ 23 Jan 2011

# This file is sourced in the update-sequence script.
# Default values are commented below.
# Un-comment and modify the values below according to the
#    layout of your system.

## SCRIPT_DIR is the directory in which you have placed
#   this script and the show-elogs script. (must end with '/')
# SCRIPT_DIR="/usr/local/sbin/"   

## STATUS_FILE is the path and basename of the status file
#   generated and used by this script. Provide the complete path
STATUS_FILE="/root/bin/update-sequence-status"

## SYNC_TS is the pathname of the file the timestamp of which will
#   be checked to determine how long it's been since the portage
#   tree was last sync'd
# SYNC_TS="/usr/portage/metadata/timestamp.chk"       # emerge --sync timestamp
#SYNC_TS="/usr/local/portage/metadata/timestamp.chk"

# MAX_AGE is the maximum time in hours since last sync before this script
#   will automatically choose to emerge --sync
# MAX_AGE=24

# ELOG_DIR is the location of elog files
# ELOG_DIR="/var/log/portage/elog/"


Code:
#!/bin/bash
# /usr/local/sbin/show-elogs
# show most recent elogs in /var/log/portage/elog/
# Author: --------------- 23 Jan 2011
#  rev 20 Mar 11 -- added latest & today options
#      01 Oct 12 -- added paged output option
#      17 Aug 14 -- bugfix: tmp_elog_summary constrained to ELOG_DIR
#Define local variables
E_BAD_ARGS=66    # improper command line argument usage exit error
E_BAD_OPT=63     # bad option exit error
BOLDon="\033[1m"
BOLDoff="\033[0m"   # escape sequences - use with "echo -e"
BLUEon="\E[34m"
LBLUEon="\E[36m"
YELLOWon="\E[33m"
GREENon="\E[32m"
REDon="\E[31m"

# set default option flags
LATEST="no"
TODAY="no"

# change if you store elogs elsewhere; must end in /
ELOG_DIR="/var/log/portage/elog/"

# function blocks
useage()
{
   echo -e $GREENon$BOLDon"Useage: show-elog [option]"$BOLDoff
   echo "  Option -h  | --help     display this text"
   echo "         -l  | --latest   display elogs for latest emerge operations only"
   echo "         -t  | --today    display elogs for today's emerge operations only"
   echo "         -p  | --paged    display elogs with paged (less) output"
   echo
   echo "  Note: User will be shown dates of emerge operations for which elog files exist"
   echo "      and be prompted for input.  Response can be any string filter.  Resulting"
   echo "      output will be the names and contents of all matching filenames. Default"
   echo "      is the most recent date found."
   echo
   echo "  Example:"
   echo -e $GREENon$BOLDon"  Enter date ["20110123"]:"$BOLDoff" 2009<enter>"
   echo "      will generate output of names and contents of all files with filename"
   echo '      matching "2009"'
   echo
   echo "  Note: You can use show-elogs in a non-interactive fashion by piping it the"
   echo "      input for its filter prompt.  You can also generate a paged display of"
   echo "      its output by piping it to less.  For example:"
   echo "         # echo 'portage' | show-elogs | less"
   echo "      to generate a paged display of elogs pertaining to the portage package."
}

find_elog_dates ()
{
# display dates for emerge operations for which elog files exist
# options: -v verbose (default) | -q silent
# returns: latest date found in format +%Y%m%d as found in filenames
[ ! "$1" = "-q" ] && echo -e $YELLOWon$BOLDon"Note: elogs exist for emerge operations run on the following dates (oldest first):"$BOLDoff
   [ ! "$1" = "-q" ] && echo -en "   "$x
   let "rem = $(expr $j % 7)"
   [ $rem -eq  0 ] && [ ! "$1" = "-q" ] && echo
   let "j = $j + 1"
done
[ ! "$1" = "-q" ] && echo -e $BOLDoff
answer="$x"  # returns latest date found for variable assignment
}

#------------------------------------------------------------------------
# start main script

# process command line argument (must be one of the following)
[ ! -z "$1" ] && case $1 in
    "-h" | "--help"    ) useage ; exit 0  ;;
    "-l" | "--latest"  ) LATEST="yes" ;;
    "-t" | "--today"   ) TODAY="yes" ;;
    "-p" | "--paged"   ) PAGED="yes" ;;
    *                  ) useage; exit 1 ;;
esac

answer=""
if [ "$TODAY" = "yes" ]
then
    answer="$(date -u +%Y%m%d)"
elif [ "$LATEST" = "yes" ]
then
    find_elog_dates -q  # quietly sets answer to latest date
else
    # prompt user to select date; default to latest
    find_elog_dates -v  # verbosely lists all elog dates
    echo
    echo -en $GREENon$BOLDon"Enter date ["$answer"]:"
    read reply
    [ ! -z $reply ] && answer=$reply
fi
# create output file and display selected elogs
[ "${ELOG_DIR:(-1)}" == "/" ] || ELOG_DIR="${ELOG_DIR}/"  # add trailing "/" if missing
[ -e "${ELOG_DIR}tmp_elog_summary" ] && rm ${ELOG_DIR}tmp_elog_summary
echo > ${ELOG_DIR}tmp_elog_summary
echo -e $GREENon$BOLDon"*  "$YELLOWon"Found the following elogs for filter: "$REDon$answer >> ${ELOG_DIR}tmp_elog_summary
echo >> ${ELOG_DIR}tmp_elog_summary

for i in $(ls $ELOG_DIR | grep $answer); do

   echo -en $GREENon$BOLDon"* "$YELLOWon ${i%%$answer*}$REDon$answer$YELLOWon${i##*$answer} $BOLDoff >> ${ELOG_DIR}tmp_elog_summary
   echo >> ${ELOG_DIR}tmp_elog_summary
   cat $ELOG_DIR$i >> ${ELOG_DIR}tmp_elog_summary
done

if [ "$PAGED" = "yes" ]
then
   less ${ELOG_DIR}tmp_elog_summary
else
   cat ${ELOG_DIR}tmp_elog_summary
fi

# clean up
[ -e "${ELOG_DIR}tmp_elog_summary" ] && rm ${ELOG_DIR}tmp_elog_summary
exit 0
Back to top
View user's profile Send private message
steveL
Advocate
Advocate


Joined: 13 Sep 2006
Posts: 3763
Location: The Peanut Gallery

PostPosted: Mon Sep 29, 2014 1:42 am    Post subject: Reply with quote

brendlefly62: Run that script past #bash (give them a url) and you will get many hints on how you can improve.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum