Replacing linked files with reals in Linux

I am new to the Linux world, but here’s what I’m trying to do if anyone can help:

My company purchased Borland’s StarTeam as our official source code management software. This includes a “universal” java client that I have running on my Win2K/Fedora Core 3 machine.

We are doing our first embedded Linux attempt, so the source code includes the source from the Linux kernel, gcc, binutils, and U-Boot as all configured and built correctly for our target platform.

Unfortunately, the makers of the above packages seem to have used shortcuts (I am still a bit weak on the difference between softlinks and hard) to include files existing elsewhere in the tree without managing the paths or copying and pasting to where they wanted them. StarTeam errors on each of these files (roughly 8,500.) So what I would like to do is to replace linked files with the real files that they were pointing to (that is, copy and paste over.)

My initial reading (in the Japanese text of “man cp”) of the -L flag to cp was that this is what it would do. However on trying to copy everything to a new directory as such:

cp -rL orig/ linkfree/

I get the following error:

cp: Will not create hard link

Any aid would be appreciated. And kindly remember this is 8,500 files so fixing these manually isn’t really feasible.

I believe that you’re using the right cp syntax (and it seems to work for me, on a quick test). An alternative you might try is tar:



tar -chf destdir/tarfile.tar sourcedir
cd destdir
tar -xf tarfile.tar
rm tarfile.tar

(if you want to be extra-cool, you can combine these into a single line, but unless you’re short on disk space this is not necessary). The h option for tar tells it to dereference links.

Summary of the difference between hard and soft links: A soft link is just a string of characters giving the directory location of the actual file (along with some flags set in the directory entry to label it as a link). A hard link is like any other ordinary file: it’s a pointer to the disk inode representing the file. If you create a hard link to an existing file, the original file and the new link have the same inode number (visible with ls -i); there’s no important distinction, to the filesystem, between the original and the link. One of the values in the file’s data structure is a linkcount, which is incremented each time a new hard link is created and decremented each time a hard link is deleted (“unlinked”). When the linkcount reaches zero the file’s disk space is freed. Hard links (unlike soft links) are restricted to all lie on the same partition.

Those are soft (symbolic) links. A soft link is a special, tiny file that just contains the name of another file that it’s pointing to. A hard link is another name for the same file, which must always be on the same device as the other hard links, and is indistinguishable from other hard links to the same file.

You could use the -h flag to tar, which causes it to archive the content of the file a symlink points to, instead of the symlink itself, then just extract the archive again:


# produce orig.tar, which contains all files and no soft links
tar cvfh orig.tar orig
# rename orig/ so we can extract to a fresh directory
mv orig orig-with-links
# produce a new orig with no soft links by extracting the tar file
tar xvf orig.tar

And on preview, I see Omphaloskeptic beat me to it. Curses! :wink:

I found a bug report on it on the Red Hat site, so it may be something recently introduced or specific to the RH/Fedora distributions. Which actually leads me to a second question, unrelated to the first.

From trying to configure yum, brub, etc. I can tell that the structure of the config files and where various stuff is kept in the file system is different among distributions. But are the actual GNU executables and kernel code different as well? Or do they mostly just take whatever GNU/Linux put out and try all the various versions together until they get a successful build and everything passes testing–then release to their customers? That is, rather than fixing or changing code to be solid, they just don’t upgrade until they are happy with the newest versions of the public stuff.

Anyway, trying the tar trick now.

-> grub

OK, I can now reproduce the error (this is under Cygwin, but I believe that hard and soft links behave about like they do in real Unices). The problem seems to occur when you try to copy both a directory and a soft link to that directory. cp thinks you’re asking it to make a hard link to the directory (a big no-no) instead of a copy of the directory, so it fails. AFAICT it should not do this.

Bug report

The tar trick didn’t work–I would get a long list of errors unpacking the tar, and then it would fail 1/6 of the way through. So right now I’m rebuilding everything in a new directory just in case I had totally messed everything up in the original directory through playing around with StarTeam. I’m pretty sure I deleted several files at least.

Much funner than doing real work. :mad:

What errors did tar give? Do you know why it failed? Are there any nested soft links (soft links to a parent directory) in the directory hierarchy? This will fail with the tar/untar method, because in that case a soft link is the only way to represent the directory structure. I can’t think of any other reasons this would fail (apart from device or special files).

You can find all of the soft links in the directory hierarchy this way:



# print locations of all soft links
find srcdir -type l -print

# print locations and destinations of all soft links
'ls' -l `find srcdir -type l -print`

This may help you understand what’s linking where.

It gave a “funou” (general) error–so I’m not sure why it failed. When I retry, if it is still failing I will try checking out a couple of the error messages to see if the locations are parent directories (though I would have thought you would get such an error when tarring with -h not when unpacking.) Though as said there were 8500 things, so if it comes to hand fixing, I’ll just take it to my managers to decide whether we want to continue using StarTeam and see if we can switch to whatever repository system Linux is using (just saw an article about it, oddly) as I woud have to assume it is built to be able to handle source code that makes liberal use of soft-links. Just don’t want to do that yet as I would have to assume we spent some good money on the software.