18

Running Ubuntu 17.04, I was installing a software from non-repository distribution, I was supposed to move the software bin -folder contents to /usr/bin (which was already iffy advice)

It's one of those days, so what I did instead:

mv /bin/* /usr/bin

So I screwed up and I accidentally moved all the files in bin to /usr/bin and /bin was empty. Since I take that /bin is system critical, for quick remedy, I copied /usr/bin contents to /bin.

Now my /bin and /usr/bin contents identical and both contain the files originally in /bin and /usr/bin separated.

  1. Is my Ubuntu in a broken state now? (Did not try to reboot the computer yet, right now everything seems to still work)
  2. Is there a way to know which files have been moved/copied to /usr/bin most recently, so I could just manually take care of the situation? 2.1 Are there usually overlapping files in /bin and /usr/bin
  3. Is there other ways to undo what I did?

I don't have Timeshift installed so restoring backups is not an option, but there's nothing critical on the computer currently, so I could just admit to screwup reinstall the whole linux partition.

  • 2
    dpkg-query -l | awk '{ system("dpkg-query -L "$2" | grep -E \"^/usr/bin/.*$\"") }' This will give you all the files initially in /usr/bin based on the packages installed – Raman Sailopal Sep 19 '17 at 9:23
  • 7
    @SatōKatsura /bin is system critical. Its content must be present at the earliest boot stages. You don't want to create a symbolic link to a partition (/usr here) which may not be mounted at boot. – xhienne Sep 19 '17 at 10:10
  • 1
    @xhienne I never said it would survive a reboot. It's a temporary fix, to get enough functionality to be able to repair the system. – Satō Katsura Sep 19 '17 at 10:18
  • 1
    @xhienne that depends on how you set up the distro. Arch, for example, doesn't maintain a separate /bin by default. Ubuntu's default partitioning does not make separate /usr partitions. I'm curious as to how many people actually do make a separate /usr with a modern distro. – muru Sep 19 '17 at 12:57
  • 1
    @muru Take my comment as a generic one. You may assume whatever you want on the number of partitions, I prefer not to and I'm warning against linking /usr/bin/* to /bin, which at best is completely useless and at worst may render the system unusable at next boot. No system that follows the FHS should contain symlinks to /usr/bin. OP was well-advised to copy the files instead. – xhienne Sep 19 '17 at 14:47
19

Is my Ubuntu in a broken state now?

Yes, your Ubuntu is broken

You messed up something important to package management.

So in practice, backup your important data (at least /etc and /home), perhaps also the list of installed packages e.g. output of dpkg -l, and reinstall Ubuntu.

(a non-novice could try to manage - like in other answers -, but then he would not have done such a huge and basic mistake)

I could just admit to screwup reinstall the whole linux partition.

That is probably what would consume less of your time. Keeping your current system with the help of other answers is keeping it in a very messy state (which would give you future headaches).

Since you are reformatting your disk, consider putting /home in a separate partition (so future such mistakes won't lose your data). Before doing that print on paper the output of df -h and df -hi and fdisk -l (they give information about disk space -both used and available- ...). Be wise to have a large enough system partition (the root file system); if you can afford it 100 Gbytes is more than enough.

I was supposed to move the software bin -folder contents to /usr/bin

(terminology: Unix have directories, not "folders").

That (moving to /usr/bin/) is very wrong. Either improve your $PATH (preferably) or at most add symlinks in /usr/bin/ and preferably move (or add symlinks) executables to /usr/local/bin/.

The wise approach is to never change /usr/bin/, /bin, /sbin, /usr/sbin/ outside of package management tools (e.g. dpkg, apt-get, aptitude, etc...). Read the FHS.

  • 4
    Going to accept this answer: it seems that after trying to recover it worked until reboot, which was unable to launch any desktop environment session anymore. Rather than trying to fix that, I'll admit my total screw up and will just reinstall the linux partition. Since everything was on version control and I had used the system for only a week, all I really lost was my dignity and had a small panic attack, but that seems to be normal when life teaches me a lesson. – oneOfThoseDays Sep 19 '17 at 15:01
  • 1
    As /bin and /usr/bin are now identical, I am not sure why package management would be screwed up. Is there really a case where /bin/foo and /usr/bin/foo are both provided by a package(s). If not, there are just some extra files floating around. – StrongBad Sep 19 '17 at 18:25
  • 3
    @Basile no it wouldn’t (be unhappy); package management only cares about files it knows about, it won’t complain about files it doesn’t know about. Even for files it does know about, it won’t be particularly bothered if they’ve changed... – Stephen Kitt Sep 20 '17 at 8:36
  • 2
    @Basile also I wouldn’t count on the latter part “(a non-novice could try to manage - like in other answers -, but then he would not have done such a huge and basic mistake)” being true ;-). Even experts slip up sometimes! – Stephen Kitt Sep 20 '17 at 8:38
  • 1
    FWIW my main system's / partition is 12GB and I never ran into space issue despite using it for development (read header files and many tools) office and design (read heavy tools), on KDE (read not-the-slimmest). Throw in 4GB more if you don't split /var, inflate by 25% if you want a larger margin than I have, and at 20GB you're more than good. – spectras Sep 21 '17 at 0:27
36

On Linux (and on most other systems, though POSIX doesn't give you that guarantee unless the move was across file systems), that would have updated their ctime, so assuming none of the other ones in /usr/bin have been touched in the last 24 hours, you should be able to move them back with:

find /usr/bin/. ! -name . -prune -ctime -1 -exec sh -c '
   echo mv -i "$@" /bin' sh {} +

Remove the echo if that looks right. Note that you won't be able to recover the files that existed by the same name in /bin and /usr/bin (the original ones in /usr/bin would have been lost)

A potential caveat: if some files were hard linked in both /bin and /usr/bin, all the hard links in /usr/bin would be moved to /bin.

Now, you may think that since /bin and /usr/bin are in the default $PATH, and /bin is available on /boot at least before /usr is mounted, it should not matter whether the executables are in /bin instead of /usr/bin.

But that would be overlooking that many commands hard code the paths of executables and expect them to be in some specific case. A common case is she-bangs. All scripts that have:

#! /usr/bin/env bash

will fail to work after you do mv /usr/bin/env /bin/env. In that regard, having the commands in both locations is safer in that it won't break those scripts.

17
  1. Your installation should be mostly OK; there shouldn’t be different files with the same name in /usr and /usr/bin (which answers your 2.1), so having all the files in both /bin and /usr/bin won’t break anything (until you upgrade packages). The only problem you might have now is broken symlinks, if you overwrote a binary with a symlink to it. To fix this, look for broken symlinks:

    find -L /bin /usr/bin -type l -ls
    

    and reinstall any packages corresponding to the files listed (for example, if /usr/bin/zsh shows up as broken, dpkg -S /bin/zsh /usr/bin/zsh will tell you which package the file came from; reinstall it with apt --reinstall install zsh).

  2. You can show and sort by ctime to see files which were recently changed (which will include files you moved):

    ls -ltc /bin
    
  3. The best approach to undo what you did is use the cruft package and delete files it finds in /bin or /usr/bin which don’t come from a package:

    sudo apt install cruft
    sudo cruft -d "/ /usr"
    

    unless the files are symlinks to files in /etc/alternatives (in which case you should leave them alone).

  • Except for scripts that start with #! /bin/sh or similar. – Satō Katsura Sep 19 '17 at 9:21
  • @SatōKatsura they would still work fine if sh is in both /bin and /usr/bin (all the files are duplicated now). – Stephen Kitt Sep 19 '17 at 9:23
  • 1
    A special toolk like cruft is not necessary for this job because the package manager also keeps track of installed files. See unix.stackexchange.com/questions/153260/… . – Ned64 Sep 19 '17 at 9:25
  • 1
    comm -12 <(ls /bin) <(ls /usr/bin) show a few entries on a Ubuntu system I tested it on. Some with a /bin/foo -> /usr/bin/foo which means foo would have been lost. – Stéphane Chazelas Sep 19 '17 at 9:26
  • @Stéphane ah yes, moving the link would nuke the original... – Stephen Kitt Sep 19 '17 at 9:29
6

It may be educational to elaborate just why your system is, to a greater or lesser extent, ‘broken’.

  1. As @basile-starynkevitch points out, the package management system has the potential to get terribly confused if it finds binaries in /bin when they should be in /usr/bin, and vice versa.
  2. Some (possibly important) scripts may be hard-wired to find a particular binary in one directory or the other (in some circumstances it's good practice, for example from a security point of view, not to rely on the contents of the $PATH).
  3. The reason why there is a distinction between /bin and /usr/bin is that the former may potentially be on a partition which is mounted at an earlier stage of the boot. In this context (ie, when booting the system), not only would /bin/xxx binaries probably be referred to by a full path, but the directory /usr/bin might not be available on the system at that point. (If you df /bin and df /usr/bin, you may see the same filesystem listed, or different ones; probably most default installs, these days, leave both directories in the same partition).

Thus you can doubless see that, if you have the same binaries in both /bin and /usr/bin, then problems 2 and 3 won't occur, and the damage from 1 might be minor. Re 1, for example, packages might not be properly uninstalled if you try to remove them; and upgrades might become garbled, if the upgrade tries to upgrade the copy in the ‘correct’ place, but ignores the copy in the ‘wrong’ place. Thus, if the above remedies seem too drastic or complicated, you might get away with leaving the system in this state.

But if this is an important system, I really wouldn't bank on that.

A general rule (again echoing @basile-starynkevitch) is never to monkey with /usr/bin, /bin and friends – they ‘belong’ to the distribution – and a package which suggests doing so as part of its normal install is... not a good package.

Edit: Relevant to point 3, there's a discussion in the context of systemd/Fedora and friends of why it makes sense to move all the contents of /bin to /usr/bin, and symlink the first to the second. This is not a recommendation that you do this, yourself – that page is addressed to the people who make distributions – but it includes some history of why this distinction exists (and by implication why it is now merely dusty tradition).

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.