LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1043|回复: 10

An easier way to update your world

[复制链接]
发表于 2006-12-6 13:03:09 | 显示全部楼层 |阅读模式
Without doubt, one of Gentoo's best features is its package management system, Portage. Portage makes it very easy to update your entire system with one simple command. Sadly, things don't always go as smooth as they should. Almost every Gentoo user has typed emerge -uD world and gone to bed with the hope of waking up in the morning to a completely up to date system. Unfortunately, it's more likely that you.ll wake up to a failed emerge on package 3 of 220. And so the troubleshoot and emerge --resume process begins.

Enter update-world to save the day. Update-world is a bash script that was recently created by count_zero and posted in the forums. The script controls the update process and forces portage to skip past failed builds and continue compiling packages until the update list is finished. Failed builds are added to a list for review once the update is finished.

Note: The script does depend on the 'equery' command, part of app-portage/gentoolkit.

Obviously before you can start using the script, you'll need to download it, put it somewhere in your path, and make it executable.

Code Listing 3.1: getting the script

# wget -O /usr/bin/update-world http://countzero.amidal.com/files/update-world
# chmod +x /usr/bin/update-world

Now we're ready to start using the script.

Code Listing 3.2: running update-world

# update-world --prepare

This begins the update process by creating a list of packages to be emerged, as produced by emerge -uD --newuse world. (Alternatively, you can use update-world --empty to create a list of all packages on the system, akin to emerge -e world). This command creates a list called 'emergelist' in ~/.update-world/. Now, you can use your favorite editor to modify this list how you like--remove packages, change versions, etc. When you have the emergelist how you like it, you're ready to move onto the next step:

Code Listing 3.3: running update-world (cont)

# update-world --install

This command actually starts the build process, just as if you had typed emerge -uD world. The difference is, if a package fails for some reason or another, that package is added to a list 'failedlist' in ~/.update-world/. Also, a link to the portage log file for that package (usually located in /var/log/portage) is created in ~/.update-world/[date]/log/. Once the process is done, you'll be presented with a list of failed packages to take care of all at once, saving much time. If you ever need to stop the process, just hit 'Control-C' to abort the process. The update can then be restarted at any time, just where it left off, by retyping update-world --install.
发表于 2006-12-6 14:07:35 | 显示全部楼层
I can't download the file,maybe the url has been crashed.
回复 支持 反对

使用道具 举报

发表于 2006-12-6 14:24:26 | 显示全部楼层
Good!!

Why not paste the script
回复 支持 反对

使用道具 举报

发表于 2006-12-6 14:32:16 | 显示全部楼层
我还是用gwn里提示的那个朴素的方案
sh -c "sudo emerge -tauvDN world || until sudo emerge --resume --skipfirst; do sudo emerge --resume --skipfirst; done"
回复 支持 反对

使用道具 举报

发表于 2006-12-6 16:10:01 | 显示全部楼层
Post by 夕角
Good!!

Why not paste the script


Would you please to paste it here?
回复 支持 反对

使用道具 举报

发表于 2006-12-7 12:21:41 | 显示全部楼层
代码在这里
http://www.gentoo.org/news/en/gwn/20061204-newsletter.xml

  1. #!/bin/bash
  2. # update-world 1.5
  3. # count_zero 2006
  4. # Licensed under the GPLv2
  5. #
  6. # update-world is a bash script that forces an emerge -uD world to continue, even
  7. # in the face of (inevitable) compile failures.  Failed builds are added to a list,
  8. # and the script jumps to the next package in the queue.
  9. #
  10. # just run update-world --prepare (or --empty) followed by update-world --install.
  11. #
  12. # Release Notes:
  13. # v1.5: now handles 'fetch restriction' properly
  14. # v1.4: uses '--newuse' for emerges to respect new use flags
  15. # v1.3: uses '--oneshot' for emerges so they don't get added to the world file.
  16. # v1.2: Script now detects log directly instead of accepting only /var/log/portage
  17. # v1.1: minor bugfix to allow package without version to be added to 'emergelist'
  18. # v1.0: Release
  19. #
  20. #
  21. # Set the program directory and important variables
  22. homedir=~/.update-world
  23. workdir="$homedir/`date +%F`"
  24. logdir="$workdir/log"
  25. mkdir -p $logdir
  26. touch $homedir/failedlist
  27. emergelist=$homedir/emergelist
  28. emergetemp=$workdir/emergetemp
  29. failedlist=$homedir/failedlist
  30. portlogdir=`cat /etc/make.conf | grep PORT_LOGDIR | sed 's/PORT_LOGDIR=//' | sed 's/"//g' | sed 's/\/$//'`
  31. masked=$homedir/masked
  32. # parameter for '--empty' to emerge -e world
  33. if [[ $1 == '--empty' || $1 == '-e' ]]
  34.    then parameter='-pev'
  35.    else parameter='-puvD --newuse'
  36. fi
  37. #### update-world --prepare ####
  38. # Prepare the list of packages to emerge into emerglist
  39. if [[ $1 == "--prepare" || $1 == "-p" || $1 == '--empty' || $1 == '-e' ]]
  40.    then
  41.    if [[ -e $emergelist ]]
  42.       then echo -n "The file 'emergelist' already exists and will be overwritten.
  43. Continue anyway? (y/n) "
  44.       read continue
  45.       if [[ $continue == 'y' || $continue == 'yes' || $continue == 'Y' || $continue == 'Yes' || $continue == 'YES' || $continue == '' ]]
  46.          then :
  47.          else echo exiting.
  48.          exit 0
  49.       fi
  50.       else :
  51.    fi
  52.    emerge $parameter world | tee $emergelist
  53.    # Make sure there are no errors in the emerge process
  54. echo
  55.    if grep -q "blocks B " $emergelist
  56.       then echo "WARNING: You have a blocking package.  Fix this before continuing."
  57.       rm -f $emergelist
  58.       exit 1
  59.       elif grep -q "masked" $emergelist
  60.       then echo "WARNING: You need to unmask some packages before continuing."
  61.       rm -f $emergelist
  62.       exit 1
  63.       elif grep -q "emerge: there are no ebuilds to satisfy" $emergelist
  64.       then echo "WARNING: One of the specified packages doesn't exist"
  65.       rm -f $emergelist
  66.       exit 1
  67.       elif grep -q 'Fetch Restriction' $emergelist
  68.       then fetchrestricted=`cat $emergelist | grep ^[[]ebuild[A-Za-z\ ]*F[A-Za-z\ ]*[]] | grep -o []][a-zA-Z0-9\/.\ -]*[[] | sed 's/\]\ //'  | sed 's/\ \[//'`
  69.       echo "WARNING: The following packages have Fetch Restriction turned on:
  70. $fetchrestricted

  71. Please download the sources from the location specified in the ebuild to /usr/portage/distfiles/ and rerun this script."
  72.       exit 1
  73.       else :
  74.    fi
  75.    echo "
  76. These are the packages that will be installed.  If you want to alter this list,
  77. just edit the file 'emergelist' in $homedir. When finished, run
  78. 'update-world --install'"
  79.    cat $emergelist | sed '/^[TC]/d' | sed 's/\[ebuild.*[ A-Z]\]\ //' | sed '/^[ ]/d' | sed '/^[ ]*$/d' | sed '/Portage\ overlays/d' | sed 's/\ .*$//' | sort -d | sed 's/.*/\=&/' > $emergetemp
  80.    mv $emergetemp $emergelist
  81.    rm -f $failedlist
  82.    exit 0
  83. #### update-world --install ####
  84. # Install the packages listed in emergelist
  85. elif [[ $1 == "--install" || $1 == "-i" ]]
  86.    then
  87.    # Verify that the emergelist doesn't produce errors
  88.    cat $emergelist | xargs emerge -p > $emergetemp
  89.    if grep -q "blocks B " $emergetemp
  90.       then echo "WARNING: You have a blocking package.  Fix this before continuing."
  91.       rm -f $emergetemp
  92.       exit 1
  93.       elif grep -q "masked" $emergelist
  94.       then echo "WARNING: You need to unmask some packages before continuing."
  95.       rm -f $emergetemp
  96.       exit 1
  97.       elif grep -q "emerge: there are no ebuilds to satisfy" $emergelist
  98.       then echo "WARNING: One of the specified packages doesn't exist"
  99.       rm -f $emergetemp
  100.       exit 1
  101.       elif [[ -z `cat $emergelist` ]]
  102.       then echo "WARNING: no 'emergelist' exists.  Did you run 'update-world --prepare' first?"
  103.       rm -f $emergetemp
  104.       exit 1
  105.       else :
  106.    fi
  107.    # Until loop to make portage continue until finished
  108.    increment=0
  109.    until [[ $increment == 1 ]]
  110.    do
  111.       cat $emergelist | xargs emerge -1
  112.       # Detect which packages have been successfully emerged and remove from the queue
  113.       installed=`tac /var/log/emerge.log | sed '/Started\ emerge/,$d' | grep "completed emerge" | sed 's/^.*)\ //' | sed 's/\ to.*//'`
  114.       for each in $installed
  115.       do
  116.          eachsed=`echo $each | sed 's|\/|\\\/|'`
  117.          if [[ -z `cat $emergelist | grep $each` ]]
  118.             then eachsed=`echo $eachsed | sed 's/\-[0-9].*//'`
  119.             else :
  120.          fi
  121.          cat $emergelist | sed "/$eachsed/d" > $emergetemp
  122.          mv $emergetemp $emergelist
  123.       done
  124.       # See if all packages have been emerged
  125.       if [[ -z `cat $emergelist` ]]
  126.          then increment=1
  127.          else :
  128.       fi
  129.       if [[ $increment == 0 ]]
  130.       then
  131.       errorlog=`ls -t $portlogdir | sed '2,$d'`
  132.       if [[ -n `cat $portlogdir/$errorlog | grep 'signal 2'` ]]
  133.          then echo "
  134. *** User hit 'Control-C' ... exiting.
  135. "
  136.          exit 1
  137.          else :
  138.       fi
  139.       sleep 5
  140.       echo
  141.       echo "*** Hit Control-C to exit, or just wait to continue with emerge."
  142.       echo
  143.       sleep 10
  144.       echo "*** Continuing with emerge."
  145.       # Detect failed emerge and add to failedlist, remove failed package from emergelist
  146.       failedpkg=`tac /var/log/emerge.log | sed '1d' | sed '/terminating/,$d' | sed '/completed\ emerge/,$d' | grep ">>>" | sed 's/.*)\ //' | sed 's/\ to.*//'`
  147.       if [[ -n `tail -n 1 $failedlist | grep $failedpkg` ]]
  148.          then echo "The failed package $failedpkg could not be merged and must be successfully installed before continuing."
  149.          exit 1
  150.          else :
  151.       fi
  152.       echo $failedpkg >> $failedlist
  153.       failedpkgsed=`echo $failedpkg | sed 's|\/|\\\/|'`
  154.       cat $emergelist | sed "/$failedpkgsed/d" > $emergetemp
  155.       mv $emergetemp $emergelist
  156.       ln -s $portlogdir/$errorlog $logdir/${errorlog}_error-log
  157.       echo
  158.       echo
  159.       echo "*** $failedpkg compile failed, skipping."
  160.       # Is there a package in 'emergelist' that requires the failed pkg as a dep? If so, remove it too.
  161.       failedpkgdeps=`echo $failedpkg | sed 's/-[0-9].*//'`
  162.       deps=`equery depends $failedpkgdeps | sed '/^\[/d' | sed 's/-[0-9].*//'`
  163.       for each in `echo $deps`
  164.       do
  165.          if [[ -n `cat $emergelist | grep "$each"` ]]
  166.             then
  167.             if [[ -n `emerge -p $each | grep "$failedpkg"` ]]
  168.                then
  169.                each2=`cat $emergelist | grep $each | sed 's/\=//'`
  170.                echo "$each2 (depends on $failedpkg)" >> $failedlist
  171.                eachsed=`echo $each | sed 's|\/|\\\/|'`
  172.                cat $emergelist | sed "/$eachsed/d" > $emergetemp
  173.                mv $emergetemp $emergelist
  174.                echo "*** $each depends on $failedpkg, skipping."
  175.                else :
  176.             fi
  177.             else :
  178.          fi
  179.       done
  180.       echo "*** Continuing with emerge world"
  181.       else :
  182.       fi
  183.    done
  184. # if improper argument is given to 'update-world' display the help text
  185. else echo "update-world 1.0
  186. count_zero 2006
  187. licensed under the GPLv2

  188. Description:
  189. This is a bash script to automate the 'emerge -uD world' process.
  190. Its purpose is to make updating the system as hands-free as possible.
  191. It does this by automatically recovering from a failed emerge and moving
  192. on to the next one, presenting the user with a list of failed packages
  193. once the update has finished.  No more 'babysitting' the update process!
  194. Just start it, and deal with any failed packages at the end.  Log files
  195. from the failed emerges are saved in the log directory.

  196. The default program directory is ~/.update-world

  197. Usage:
  198. update-world [--prepare | -p ]
  199.    Prepares a list of packages produced by 'emerge -puvD world'
  200.    and outputs them to the file 'emergelist' in the current directory.
  201.    Add, remove, or change the version of any of the packages listed
  202.    in this file with your favorite editor before continuing.
  203. update-world [--empty | -e ]
  204.    Same as --prepare except it performs 'emerge -ev world' to recompile
  205.    all packages on a system.
  206. update-world [--install | -i ]
  207.    Begins the emerge process based upon the 'emergelist' file created
  208.    from running 'update-world --prepare'.  Once finished, failed builds
  209.    will be saved in the file 'failedlist' in the current directory."
  210. exit 1
  211. fi


  212. echo "Congratulations!  'emerge world' complete."
  213. echo
  214. # All done! display the failed packages, if any
  215. if [[ -z `cat $failedlist` ]]
  216.    then echo "All packages emerged successfully"
  217.    else echo "These packages couldn't be merged due to compile errors:"
  218.    echo
  219.    cat $failedlist
  220.    echo
  221.    echo "Look in $logdir/ for the portage log files of the failed builds.
  222. Check bugs.gentoo.org or the Gentoo Forums for help."
  223. fi
  224. exit 0
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-12-8 11:10:51 | 显示全部楼层


3qx a lot
回复 支持 反对

使用道具 举报

发表于 2006-12-8 11:20:50 | 显示全部楼层
我也是刚看到周报上的这个消息,果然sir上已经贴出。

终于可以象freebsd的port系统,敲个命令就去安心大睡了
回复 支持 反对

使用道具 举报

发表于 2006-12-8 19:32:59 | 显示全部楼层
不错,不错!
回复 支持 反对

使用道具 举报

发表于 2006-12-8 19:33:04 | 显示全部楼层
不错,不错!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表