6

Years ago I copied all the files from /usr/local/bin into /bin.

Now my /bin directory is littered with unneeded files. How do I remove them using the find command without having to install third party packages?

Note: Answers involving third party packages may be helpful to others who have the same question.

  • I would search by changed timestamp – bac0n Jul 1 at 20:12
  • cp /usr/local/bin /bin shouldn't copy any files. It should print the error message cp: -r not specified; omitting directory '/usr/local/bin'. Are you sure that's the command you ran? – Eliah Kagan Jul 1 at 21:03
  • @EliahKagan It was in 2017 the command was run by accident and I don't remember doing it. I will revise the question with the question with -r flag. – WinEunuuchs2Unix Jul 1 at 21:56
  • cp -r /usr/local/bin /bin places all copied files in /bin/bin, which is very easy to fix. Are you sure that's the command you ran? One of my concerns is that people who have run the command(s) mentioned in this question (or variations on them) may find this question by searching, wrongly assume they have a complicated problem, and attempt to follow advice in answers here that is inappropriate for their use case and that, especially if followed wrongly, would turn a problem that is easy to fix (or a total non-problem) into a problem that is hard or impossible to fix. – Eliah Kagan Jul 1 at 21:59
  • 2
    @EliahKagan I see your point. Fact is I don't know how the files were copied so I've removed the cp command altogether. – WinEunuuchs2Unix Jul 1 at 22:09
8

Piece together solutions available in Stack Exchange.

If you do enough research you will find a solution by combining these five answers:

Trial Run

First run the command without rm (remove) option to ensure correct files are being found:

$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}'

/bin/.auto-brightness-config
/bin/auto-brightness-config
/bin/bell
/bin/bell/bell-select-menu
    ( ... OUTPUT SHORTENED ... )

How it works

find returns the filenames in Directory 1 (/usr/local/bin) followed by Directory 2 (/bin(:

Directory 1 Files in no particular order

  • bbbbb
  • aaaaa
  • yyyyy

Directory 2 Files in no particular order

  • echo
  • aaaaa
  • zcat
  • bbbbb
  • egrep
  • yyyyy

sort sorts the two directories' filenames alphabetically

  • aaaaa
  • aaaaa
  • bbbbb
  • bbbbb
  • echo
  • egrep
  • yyyyy
  • yyyyy
  • zcat

uniq -d reports only the duplicates

  • aaaaa
  • bbbbb
  • yyyyy

This gives us a list of Directory 1 filenames that were accidentally copied into Directory 2. But there is a blank line at the top of the list.

tail -n +2 removed the blank line at the top of the list.

awk '{print "/bin/" $0}' prepends /bin/ to each filename so we have:

  • /bin/aaaaa
  • /bin/bbbbb
  • /bin/yyyyy

Append the rm command to pipeline

Now that we've confirmed output is correct append the rm command via xargs. Note if you have filenames with special characters read the fourth link above for exceptional handling.

$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}' | xargs rm -f
rm: cannot remove '/bin/.auto-brightness-config': Permission denied
rm: cannot remove '/bin/auto-brightness-config': Permission denied
rm: cannot remove '/bin/bell': Is a directory
rm: cannot remove '/bin/bell/bell-select-menu': Permission denied

The Permission denied error appears because we must use sudo powers to run the command. Note the error '/bin/bell' is a directory. Later we will have to manually removed the directory with rm -d command.

sudo powers required for /bin directory.

The reason permission denied errors occurred is because root owns the files in /bin we want to delete and our regular user ID isn't allowed to delete them.

Note depending on how you copied the files into the target directory you may not need need sudo powers to delete them. For example if you are defined as the owner of the files in the target directory.

Now lets run command with sudo powers:

$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}' | sudo xargs rm -f
rm: cannot remove '/bin/bell': Is a directory
rm: cannot remove '/bin/bell/sounds': Is a directory
rm: cannot remove '/bin/startup-scripts': Is a directory
rm: cannot remove '/bin/zap': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello/BeOS': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello/FreeBSD': Is a directory
rm: cannot remove '/bin/zap/Assembly-Intro-hello/Linux': Is a directory

75 files have been deleted but 8 empty sub-directories are left to remove. We use the -r recursive option with rm command to delete them:

$ find /usr/local/bin/ /bin/ -printf '%P\n' | sort | uniq -d | tail -n +2 | awk '{print "/bin/" $0}' | sudo xargs rm -rf

Nothing is reported so no more errors!

Summary

The objective of this answer is to not only solve the problem at hand but show the reader how a problem can be solved by checking multiple existing answers in Stack Exchange.

| improve this answer | |
  • -1 because you don't explain what you are actually doing, especially how you determine which files are unneeded. – danzel Jul 2 at 18:23
  • @danzel I expanded the answer with explanations of find, sort, uniq, tail and awk commands. – WinEunuuchs2Unix Jul 3 at 11:49
4

Your method is great, but looks too long.

While transforming Linux Mint to Ubuntu I have used the command like:

sudo find /bin -type f -exec dpkg -S {} \; 2> ~/Desktop/not-in-apt.out

and as the result for your case we will get wrong copied files list in ~/Desktop/not-in-apt.out.

You can then review the file and remove files listed in it. Or use some scripting for removal.

To be completely sure that all remaining files in /bin are normal you can reinstall them by combining dpkg -S /bin with apt-get install --reinstall with something like

sudo apt-get install --reinstall $(dpkg -S /bin | sed 's|: /bin||' | sed 's/,//g')
| improve this answer | |
  • This is uncanny because what led me to the Q&A is something is zero'ing out /bin/echo which breaks xarg command which breaks screenfetch command. I had to use dpkg -S /bin/echo to find out I needed to use sudo apt install --reinstall coreutils. – WinEunuuchs2Unix Jul 1 at 22:00
  • Edited to add sudo apt-get install --reinstall ... part. – N0rbert Jul 2 at 7:48
  • I really like that you're using dpkg -S instead of relying on timestamps. Note that this technique is available for rpm or pacman-based distros, too. Search for dpkg -S in this listing to find the translation to your distro. – jpaugh Jul 2 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.