Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

soft links, relative to other soft-links... 1

Status
Not open for further replies.

shadedecho

Programmer
Oct 4, 2002
336
US
Ok, I know this is gonna sound a bit strange, but here is what I'm trying to accomplish in my file system, and I thought I could do it easily with soft-links:

/ test.txt
test-dir/:
blah.txt --> ../test.txt

/ test.txt
test-dir --> /
Essentially, I want to have a soft-link inside of dir-a/test-dir which points to ../test.txt, meaning a relative soft-link to the file in whatever its parent directory is. This part works just fine.

Then, if I am inside of dir-b/test-dir (which is itself a soft-link to actually dir-a/test-dir), i thought that the soft-link would "follow" the relative positioning of the symlink, meaning that if referencing dir-b/test-dir, that directory would then be referencing dir-b/test.txt.

If I do "cd / and then do "cd ..", I am physically in / not the actual parent of test-dir, which would be "dir-a". The "cd" command respected the relative positioning like I would want.

However, if I do "cd / and I then do "vi ../test.txt", it is actually letting me see dir-a/test.txt, not dir-b/test.txt like I would want.

Is there a way to have the link inside of "test-dir" so that it actually does reference any relative sym-linked parent who is used to access it, for the reading (de-referencing) of files, instead of the absolute parent, when "../test.txt" is specified?
 
If I understand your question, I doubt it.

Even if you're not using Bash as your shell, the Bash manual can probably explain it better than I would. This section descripbes the [tt]-P[/tt] option to the bash [tt]set[/tt] builtin:


-- START MANUAL ENTRY --

If set, do not follow symbolic links when performing commands such as `cd' which change the current directory. The physical directory is used instead. By default, Bash follows the logical chain of directories when performing commands which change the current directory.

For example, if `/usr/sys' is a symbolic link to `/usr/local/sys' then:
Code:
$ cd /usr/sys; echo $PWD
/usr/sys
$ cd ..; pwd
/usr

If `set -P' is on, then:
Code:
$ cd /usr/sys; echo $PWD
/usr/local/sys
$ cd ..; pwd
/usr/local

-- END MANUAL ENTRY --


So, really, the only reason your [tt]cd[/tt] trick works is that the shell specially supports it (by default).

If you don't use Bash, then you can look in your shell's documentation to figure out what exactly it's doing and how and why. There might be a workaround to get the behavior you want.

I bet if you really, really wanted to, you could hack Bash to do the trick for all paths you specify on the command line. I bet you'd break a lot of things by doing that, though.
 
Well I'm glad to understand why my bash shell is respecting the following of the symlinks, whereas vi and other such reading/dereferencing of files is not.

BTW, what is the actual difference between a hard-link and a soft-link, except that a hard link cannot be made to a directory?

Essentially, what I have is a web tool called "phpMyAdmin" which I want to deploy ONCE on my web server, but let multiple virtual customers use it, via symlinks and apache. This works fine. But I then got to thinking, well what if each customer wanted to use the core code for phpMyAdmin, but have their own version of "config.inc.php" file... so that's what got me thinking about the above directory structure and methodology.

Is there any way you can think of which would allow me to have a single directory with the files for phpMyAdmin, and have it "tricked" into using a different version of a local file in its directory based on "who" accesses it, that is through the apache conf of one web client, versus another?
 
> BTW, what is the actual difference between a hard-link
> and a soft-link, except that a hard link cannot be made
> to a directory?

So... do this:
Code:
$ echo "glarg" > ~/dir-1/foo.txt

You've now modified a bunch of bits on your disk to contain the ASCII codes for the characters "glarg". You've also created a "thing" that knows where those bits are located on the disk; that thing is called an inode.

You've also modified the set of bits associated with the directory [tt]~/dir-1[/tt] to contain a character string "[tt]foo.txt[/tt]" that "points to" that inode.


Now, do:
Code:
$ ln ~/dir-1/foo.txt ~/dir-2/bar.txt

Now, you've modified the bits of the directory [tt]~/dir-2[/tt] to contain a character string "[tt]bar.txt[/tt]" that "points to" the same inode we've been talking about (the one that knows where "glarg" is).

So you have two filenames that refer to the same inode. Neither filename is more "real" than the other; they're both essentially the same thing. If you delete either one, there will still be a file cotnaining "glarg".

But now, do:
Code:
$ ln -s ../dir-1/foo.txt ~/dir-3/frob.txt

This time, you've created a new set of bits that contain the string, "[tt]../dir-1/foo.txt[/tt]"; this set of bits has its own inode.

Now, you have one filename that refers to the inode containing the data, and one filename that refers to a "special" file that points to the other filename. The "real" filename is, of course, more "real." If you delete the symbolic link, you still have the real file containing "glarg"; if you delete the "real" file, the symbolic link stays there, but it points to a nonexistant file.


Also, since directories can only point to inodes on the same filesystem as themselves, you can't make a hard link to a file on another filesystem; you must use a soft link.


Hard links are probably a tiny bit faster than symbolic links.



I'll have to let someone else handle the PHP/Apache stuff.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top