# Script that will list package deps. that can be removed

## Naan Yaar

When you uninstall a package in emerge, there is currently no way to tell:

a. what packages were installed because of this package

b. if you could list items in a., which ones could you remove without breaking dependencies in other packages.

The following script does this.

(Updated with minor clean-up)

7/24/02: minor fix-up to "echo Usage" based on feedback from Dolio below.

```

#!/bin/bash

#

# Finds out dependencies of a package that CAN be removed when a package is

# uninstalled.  Basic procedure is as follows:

# a. construct a list of dependencies for the package using emerge -pe.  This

#    is the list of items that will tentatively be removed

# b. go through the list of installed packages and create a list with these

#    packages minus the list of dependencies and masked packages

# c. construct a list of dependencies for the list from step b.

# d. construct list of dependencies from a. that can be removed, based on

#    checks against c and world packages

#

# NB.

# a. Make sure you go through the list it suggests and cull any dubious items

# b. Versions are stripped out of all checks.  So it may be over conservative

#    in suggesting removals.  This is good :)

if [ $# == 0 ]; then

        echo -e 'Usage: '$0' [package...]'

        echo -e 'where package is a full or partial name of an installed package'

        exit

fi

# Need recent version of portage in order to test for masked packages.

# One could root through the masked package list, but that would be too hard :)

pv=(`emerge --version|sed 's/Portage \([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/\1 \2 \3/g'`)

if (( ${pv[0]} < 2 || (( ${pv[0]} == 2 && ${pv[1]} == 0 && ${pv[2]} < 13 )) )); then

        echo -e 'Incorrect portage version'

        echo -e 'Need 2.0.13 or greater'

        exit

fi

# useful sed strings

ebuild_strip='s/^\[ebuild[^]]*\] \([^ ]*\) .*/\1/g'

hdr_del='1,4d'

last_del='$d'

rev_strip='s/-r[0-9]\+$//'

ver_strip='s/-[0-9][^-]*$//'

mask_strip='s/^.\{20\}\(.*\).\{27\}$/\1/g'

# dependencies of the package that will be removed

contents=`emerge -pe $@ | sed -e "$ebuild_strip" -e "$hdr_del" -e "$last_del" -e "$rev_strip" -e "$ver_strip"`

# masked packages

masked=`emerge -s "." | grep Masked | sed -e "$mask_strip"`

# look through installed packages to build a list with following exceptions

# a. packages whose ebuilds are not in portage

# b. packages that are dependencies of the package to be uninstalled

# c. packages that are masked

for instpkg in `/usr/lib/portage/bin/pkglist | sed -e "$rev_strip" -e "$ver_strip"`; do

        for chk in $contents $masked; do

                if [ $instpkg == $chk ]; then

                        continue 2

                fi

        done

        if [ -e /usr/portage/$instpkg ]; then

                allinst="$allinst $instpkg"

        else

                # for packages that have been moved, use the package name alone

                # build the list separately in case package is really gone

                instpkg=`echo $instpkg | sed 's:^[^/]*/::g'`

                allneeded="$allneeded `emerge -pe $instpkg | sed -e "$ebuild_strip" -e "$hdr_del" -e "$last_del" -e "$rev_strip" -e "$ver_strip"`"

        fi

done

# generate list of dependencies of 'all' installed packages

allneeded="$allneeded `emerge -pe $allinst | sed -e "$ebuild_strip" -e "$hdr_del" -e "$last_del" -e "$rev_strip" -e "$ver_strip"`"

# top level packages that should not be removed

world=`emerge -pe --nodeps world | sed -e "$ebuild_strip" -e "$hdr_del" -e "$last_del" -e "$rev_strip" -e "$ver_strip"`

# finally, packages can be removed only if they are not in the world

# or needed lists

{

        for pkg in $contents; do

                for need in $allneeded $world; do

                        if [ $pkg == $need ]; then

                                continue 2

                        fi

                done

                echo $pkg

        done

} | sort | uniq

```

Last edited by Naan Yaar on Wed Jul 24, 2002 11:30 am; edited 3 times in total

----------

## BonezTheGoon

Wow, thanks!!!  That is surely impressive, I will have to run some tests on this--but it looks really good!  Nice job, maybe we can get this added into portage at some point??  You might consider asking to have this moved from tips and tricks to suggestions.  Very slick!!

Thanks again,

BonezTheGoon

----------

## Naan Yaar

Thanks.  Let me know if you find any issues with this.

I believe that portage will implement "backward" dependencies sometime soon.  I just couldn't wait till then  :Smile: 

----------

## Black666

Nice!! The only feature I was missing in portage so far.

----------

## niyogi

anybody know whether this is in Portage's "to-do" list?

-S

----------

## Dolio

One little thing (not a big deal). On the usage, you used single quotes on the "echo '$0 ...'" so it actually prints out $0 instead of the first argument. Not sure if that's what you wanted.

----------

## Naan Yaar

Thanks.  Wasn't meant to do that  :Smile:   I have actually seen it spew out $0 while testing without really having it register!

 *Dolio wrote:*   

> One little thing (not a big deal). On the usage, you used single quotes on the "echo '$0 ...'" so it actually prints out $0 instead of the first argument. Not sure if that's what you wanted.

 

----------

## shoot2kill

Now I know the list of packages which can be removed safely. How do I remove them? This can be done all at once at a time or one package at a time?

----------

## niyogi

it looks like this script executes silently... you have no idea what it's doing and then it brings you back to the prompt.  

perhaps a "-v" parameter that lets you see what's happening behind the scenes.

also, usually what can happen is somebody will unmerge a package and then say "oh man.  what dependencies were there?"  but this script can't handle that... it can only handle those that are still installed and want to be uninstalled along with any orphaned dependencies.

still a great script to keep your system streamlined!  :Smile: 

-niyogi

----------

## Naan Yaar

In the grand old Unix tradition  :Smile:   Seriously, I don't like colored and pretty formatted output that cannot be turned off since you have to do gory sed/awk hacks to strip the crud off.  The -v option is a good idea - I was thinking about it too.

 *Quote:*   

> it looks like this script executes silently... you have no idea what it's doing and then it brings you back to the prompt.  
> 
> perhaps a "-v" parameter that lets you see what's happening behind the scenes.
> 
> 

 

I think this should be handled correctly.  I tested it with packages that have not been installed yet.  For example, I do emerge -pu wampager (which I don't have installed).  It gave me wampager and a few other packages.  When I do <script> wampager, it did give me what could have been cleanly removed if wampager was installed and then uninstalled (it does emerge -pe to get the dependenices of the specified package - it does not really matter whether it is installed).

 *Quote:*   

> 
> 
> also, usually what can happen is somebody will unmerge a package and then say "oh man.  what dependencies were there?"  but this script can't handle that... it can only handle those that are still installed and want to be uninstalled along with any orphaned dependencies.
> 
> 

 

Thanks.   :Smile:   It is a bit of a fudge, but still useful.

 *Quote:*   

> 
> 
> still a great script to keep your system streamlined! 
> 
> -niyogi

 

----------

## Naan Yaar

```

emerge unmerge <package_names>

```

Can do more than one at a time.

 *shoot2kill wrote:*   

> Now I know the list of packages which can be removed safely. How do I remove them? This can be done all at once at a time or one package at a time?

 

----------

## shoot2kill

Why is that the packages that i have already unmerged, are still showing from the list when using the scripts to check.

----------

## Naan Yaar

Can you provide more details?  Could be different versions.

 *Quote:*   

> 
> 
> Why is that the packages that i have already unmerged, are still showing from the list when using the scripts to check.
> 
> 

 

----------

## shoot2kill

I am trying to remove the kde3 packages, I have removed most of the packages but stilll showing from the list when again using the script to check.

----------

## Naan Yaar

Yes.  It assumes that the package is installed fully (since it does an "emerge -pe").  If you can't see it not installed in emerge you are OK.

I was doing this to enable testing.

----------

## shippy

Unfortunately, this script doesn't work for me. I'm using Portage 2.0.36 under Gentoo 1.4_rc1. Whenever I run it, I get:

```

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

/usr/bin/unmerge_list: [: too many arguments

```

And this goes on forever (as far as I can tell).

----------

## arkane

 *shippy wrote:*   

> Unfortunately, this script doesn't work for me. I'm using Portage 2.0.36 under Gentoo 1.4_rc1. Whenever I run it, I get:
> 
> ```
> 
> /usr/bin/unmerge_list: [: too many arguments
> ...

 

yeah, I just tested it, and it does the same thing for me.

I'm using Portage 2.0.38, myself.

EDIT: gcc 2.95, if that even matters  :Smile:   It shouldn't but I'm posting it to counter the last post saying gentoo 1.4_rc1.

----------

## Hypnos

Works nicely ... I used it to remove GNOME since I'm a Fluxbox devotee now.

Good job!

It'll be cool when the functionality is incorporated in the stock emerge.

----------

## digitalnick

i get same error on mine too many argumensts ... anyone know whats goin on?

----------

## craftyc

When I run the script, it wants to remove baselayout! What went wrong?

----------

## H-Pi

 *craftyc wrote:*   

> When I run the script, it wants to remove baselayout! What went wrong?

 

depends on which parameters you gave (whcih package you want to remove)

you do <script> <package>, so if you choose a package of which baselayout is a dep and it's no dep for other programs, the script says it can be removet

( think it's something like this, I must say I haven't studied the script too much  :Smile: )

----------

## y0el

Umm... Forget my post... I got a little error in the script when I pasted it.   :Embarassed: 

The script works great! Good job!

Something similar built into portage would make Gentoo even better...

----------

## holek

I have a problem with this script.

When i run it i get no output at all  :/

it's doing something cause my cpu usage is going to 99%

It does it for a while then stops, scripts ends without errors, but there is nothing on the console.

I f somebody could help me i would appriciate it very much.

----------

## Crazor

Can't help, but this script seems to do some weird stuff.

For example, running it on dev-java\sun-jdk-1.4.1.02-r1 gives some strange output:

```
"sun-jdk-1.4.1.02-r1".

are

ebuilds

emerge:

masked

no

satisfy

there

unmasked
```

also, it is running for quite a long time before outputting anything. is it normal that it is that slow?

[edit]been too fast with complaining. this strange output is only happening with the sun-jdk. with other packages, it works fine[/edit]

----------

## garo

Why do you need this script when you have "emerge depclean" ?

----------

## Naan Yaar

This script preceded the depclean option in emerge (July vs. Oct. 2002).  I imagine it is not needed now, but I haven't used depclean much to be certain...

 *garo wrote:*   

> Why do you need this script when you have "emerge depclean" ?

 

----------

## Crazor

lol, haven't realized this being in portage now =)

have to check this when i get home and out of the windoze world

----------

## rojaro

 *garo wrote:*   

> Why do you need this script when you have "emerge depclean" ?

 

right, but you never should use this command without the "pretend" parameter e.g. emerge depclean -p or emerge depclean --pretend. otherwise you can run in serious trouble - e.g. i got grub and lilo installed on my machine - i use grub for booting locally and lilo for stuff like bootdisks. if i run depclean it also wants to remove grub (and usbutils, pciutils and even iptables which i use every day for port redircetions and nat) - so it would be a bad idea to let it run without -p. but indeed - this command is still pretty usefull and i found two packages which i could safely remove.

but i think the whole concept behind portage is still somewhat flawed and needs to be revamped/rewritten in some parts, but it's surely the best one available for linux.

----------

## choenig

 *garo wrote:*   

> Why do you need this script when you have "emerge depclean" ?

 

This has nothing to do with depclean! 

If you call depclean, you clean (or pretend to do so) your whole installed tree. 

This script only tells you, what can be unmerged safely if you get rid of ONE requested ebuild.

@Naan Yaar

I was thinking of this idea, too.

Theoreticaly a (simplyfied)

```

for i in `emerge -ep $EBUILD` ; do dep=$(qpkg -q $i) ; if [ ! -n "$dep" ] ; then echo  $i;fi;done

```

would do the thing, except that this doesn't care about the magic 'system'. 

Is there any way to find out, which ebuilds are part of 'system' ?

take care, have fun

/christian

----------

## Jarjar

 *garo wrote:*   

> Why do you need this script when you have "emerge depclean" ?

 

Are you sure depclean existed in portage when this thread was started?

----------

## Naan Yaar

This would still need some work.  qpkg -q output will contain the following:

a. the package that is going to be (potentially) uninstalled, i.e., the "parent" package

b. packages that are dependencies of the parent package and depend on the queried package; these may be packages that are not needed by anything else though

c. self

a, b, and c would need to be discounted.

In addition, there was some funkiness with masked and moved packages when I wrote the script.  Hence all the shenanigans.  Also "qpkg -q" did not exist when I wrote the script.

 *nevertheless wrote:*   

> ...
> 
> @Naan Yaar
> 
> I was thinking of this idea, too.
> ...

 

----------

## choenig

 *Naan Yaar wrote:*   

> This would still need some work.  qpkg -q output will contain the following:
> 
> a. the package that is going to be (potentially) uninstalled, i.e., the "parent" package
> 
> b. packages that are dependencies of the parent package and depend on the queried package; these may be packages that are not needed by anything else though
> ...

 

I think you missunderstood my point.

My little bash-script is simplified. The real one looked like this:

```

for i in `emerge -ep cdrtools | grep "\[ebuild" | sed s/'\[.*] '/''/g` ; do dep=$(qpkg -q $i | egrep '^[[:space:]]') ; if [ ! -n "$dep" ] ; then echo  $i;fi;done

```

So, what this does is to check all ebuilds, $EBUILD depends on (emerge -ep $EBUILD) and checks for each of those, if it is dependend on by some ebuild (qpkg -q). Only if there is no package, which needs this, it will be echo'ed.

BUT: The problem with this thing is, that it also echoes packages, which are part of the 'system' thing of portage and I don't know how to find out, which packages are part of 'system'.

take care, have fun

/christian

----------

## Naan Yaar

Once again, your script will not work correctly unless you remove dependencies (including transitive ones) that are "rooted" at the package you are trying to query, e.g., cdrtools.

"System" packages are listed in /usr/portage/profiles/default/packages, BTW.

 *nevertheless wrote:*   

> 
> 
> I think you missunderstood my point.
> 
> My little bash-script is simplified. The real one looked like this:
> ...

 

----------

## tecknojunky

I have gave up a long time ago to see a decent packages clean up for gentoo.

Pretending depclean list things that makes you wonder "why?".  reiserfsprogs?  Why?  Evolution?  Why?  ... and many more I installed.

Others show up that you know they must have been installed as dependencies but you have no clue to which, then start the qpkg game.

So I just forget about them.  When I'll find my system way too bloated, i'll reinstall from scratch (just like in the good'il windows 98 times).

Someone mentionned that the portage system is flawed and I agree, but nothing can't be built in a nanoseconds.  There are a lot of things I dislike about it, but it's the best sourced dependencies system there is... for the time being.  :Wink: 

----------

## nianderson

when i run the script i get 

```

line 54: [: too many arguments

```

line 49 is 

```

masked=`emerge -s "." | grep Masked | sed -e "$mask_        strip"`

```

and lits comments to line 52 which is 

 *Quote:*   

> 
> 
> or instpkg in `/usr/lib/portage/bin/pkglist | sed -        e "$rev_strip" -e "$ver_strip"`; do
> 
> ```
> ...

 

----------

## infamousmrsatan

I have a problem with this script -- it depends on pkglist which is no longer being included with portage?? (Or I don't have it for somereason anyway)

Naan Yaar... would it be too much to ask you to modify the  script to work using qpkg -I instead ??

Thanks,

Justin

----------

