How identify the source file as a hard link? Bash Script - bash

I'm making a shell script that identifies hard links to a directory, but I need to know the source file.
example:
Ln origen1.txt destino1.txt
Ln origen1.txt destino2.txt
Ln origen1.txt destino2.txt
The output should be origen1.txt, because this is the source file for other hard links. This should be in bash. I need help, Thank you.

You can't. If you have a file file1, and you create a hardlink to it using ln:
ln file1 file2
Then the two files are indistinguishable. A "hard link" is really just the same thing as a normal file entry; it just happens to point to the same file as another entry. You can remove either one and you're back to having a single "hard link" to the file.

Like people have pointed out, hard links are all equivalent. However, you can use find to find all the hard links of a file:
find / -samefile destino2.txt
It won't say which link was the first one, but it will tell you all the possible candidates.

Related

Bash: Find which symbolic links exists to a specific file

Given a file somewhere in the file system, can I find out which symbolic links exists that point to that file?
The purpose of this would be to determine if a file can be successfully deleted, or if deleting the file would leave behind a bunch of dead symbolic links.
If you do an "ls -l" in a directory that contains a file which is a symbolic link, the ls command will show you where the link goes. I'm looking for the reverse of that, which is getting a list of symbolic links around the file system which point to a specific file.
For example:
$ ls --optionToFindSymLinks? ./thefile.txt
/home/user/dir/file.txt -> ./thefile.txt
/home/otheruser/dir/file2.txt -> ./thefile.txt
2 symbolic links found
I realise that unmounted file systems might contain links that I won't be able to find, but this would not be a problem in my case.
Edit: Attempt at clarification
There is no reverse search. You have to do the work yourself. Get a list of all the symbolic links in your system and check which of them point to the file you are interested in.

Can't see files with Symlink

I need my client to be able to see the file in the directory they are allowed on. So I soft link the directory they are allowed on but can't see the files inside even tho they have the right (rwx).
ex:
/home/user1/project1.link/(couple of files)**
/clients/client_shamwow/project1/(couples of files)
**: Can't see the files.
This is the line I used:
ln -s /clients/client_shamwow/projet_prod /home/user1/projet_prod
is there something wrong that I am doing so they can't see the files in project_prod or I should use something else?
Your command doesn't match your example, but I assume you mean /home/user1/project1.link is a soft (symbolic) link, and when you run ls it lists just that name, rather than the contents of the directory the link points to. If that's the case, add the -L option to your ls command.
ls -lL /home/user1/project1.link
The man page says:
-L, --dereference
when showing file information for a symbolic link, show information
for the file the link references rather than for the link itself
Another way is simply to append /. to the end of your command, as in
ls -l /home/user1/project1.link/.
If that doesn't answer your question, I think you need to be more clear, and perhaps clean up the inconsistencies in your question. Even show some real output and the commands you ran.
Solved. No idea what happend. I just recreated the link the exact same way I did before and now I am able to see AND modify the files as the user1 w/o him being able to go anywhere else than what is in the folder project_prod. Thx for your time :)

Linux: The command ls -la shows a file pointing to another file. What does that mean?

When I type ls -la to list all the files, I see this:
11 Jul 9 12:04 libcrypto.so -> libcrypto.so.0
I tried to change the name of libcrypto:
mv libcryto.so libpmcrypto.so
And now it shows:
11 Jul 9 12:04 libpmcrypto.so -> libcrypto.so.0
Does that affect anything? And what does the arrow mean?
The file in question is a symbolic link. This is conceptually similar to the idea of a shortcut, but it appears to be the real file if you use it (Open it, copy it, etc.). The symbolic link is another name that "points to" the real file. When you do ls -l it also shows you which file is pointed to by the link. Renaming the link has no effect on the original file, but may break things that rely on the link name, just as with any other file name. Deleting the link just removes the pointer, and has no effect on the original file. Deleting the original file will leave the link in a "broken state" where the link points to nothing.
Edit
You can't really edit what symbolic links point to. You can delete them with rm and then recreate them with the ln -s command. Take a look at the man pages for more information.
-> means libpmcrypto.so is a Symbolic link and the information stored in libcrypto.so.0 is accessible through the libpmcrypto.so file.
How to create a symbolic link:
ln -s [TARGET DIRECTORY OR FILE] ./[SHORTCUT]
for example:
ln -s /usr/local/apache/logs /home/el/logs
If you delete the soft link itself (/home/el/logs), the file (/usr/local/apache/logs) would still be there.
How to find symbolic links:
find ./ -type l
read man ln for more information on links.
ls -la will display files pointing to module using symbolic links
For example in your library directory you have file pointing to the .so files (shared object).
This means it does not need to be recompiled. You have no easy way of telling how files are linked.
Yes that does changes something, in fact you shouldn't change a shared library because when a 3rd-party program tries to call libcryto.so its not going to be there any more.
But if you're sure you want to change the name, I would recommend you to call nautilus in superuser mode:
sudo nautilus /THE/FOLDER/WHERE/YOUR/FILE/IS
And edit it manually, by adding .0 to the end of the symlink name. You're changing part of its name so whenever a program tries to call it, its not going to be able to locate it.

Copying directories recursively using shell script

Should be an easy question for the gurus here, though it's hard to explain it in text so hopefully this is clear. I've got two directories on a box with some flavor of unix on it. I've got a script that I want to use to move all the files and directories from one location to another.
First, an example of how the directories look:
Directory A: final/results/2012/2012-02/2012-02-25/name/files
Directory B: test/results/2012/2012-02/2012-02-24/name/files
So you see they're very similar. What I want to do is move everything from the Directory B 2012 directory, recursively, to the same level of Directory A. So you'd end up with:
someproject/results/2012/2012-02/2012-02-25/name/files
someproject/results/2012/2012-02/2012-02-24/name/files
etc.
I want this script to be future proof though, meaning I don't want the 2012 hardcoded. Also, towards the end of a month you will potentially have data from two different months and both need to be copied into the 2012 directory. So here is the command I used in the shell script file:
CONS="/someproject";
ROOT="/test";
/bin/cp -r ${ROOT}/results/* ${CONS}/results/*
but this resulted in:
/final/results/2012/2012-02/2012-02-25/name/files
and
/final/results/2012/2012/2012-02/2012-02-24/name/files
So as I hope is clear, it started a level below where I wanted it too. Can anyone fill me in on what I'm doing wrong, if they can understand what I'm even trying to explain. My apologies if it's not clear. I'm sure this is a fairly simple fix but I'm not sure what to do. Shell scripting is not a strong point of mine.
One poster suggests rsync, which is overkill.
cp -rp will work fine. if you want to move the files, just mv the directory -- it and everything under it will move too.
The only real problem here is the use of terminating *'s in the command line in the original script. You don't need the *, you're just trying to pass directories to the cp command, you aren't trying to pass it the names of all the files already in the source (and more importantly, the destination).
You could also use a tool like rsync to make sure your source and target are synchronized.
rsync -av ${ROOT}/results/ ${CONS}/results/
You specified that you want to "move" the files, though. Which means deleting the originals after they're copied:
rsync -av --remove-source-files ${ROOT}/results/ ${CONS}/results/
If you start playing around with rsync, be sure to read the man page about how it treats trailing slashes.

Symbolic Links in Ubuntu Recursively link to files in one directory to another

After searching stackoverflow and Google for the past hour I thought I would ask. If the title does not make sense here is what I am looking to achieve.
/var/www/xxx/
Say there are files in this above directory.
/var/www/yyy/
I want the files found in directory xxx to be symbolically linked within directory yyy.
I cannot figure out how to get the symbolic links to work as such:
/var/www/yyy/filefromfolderxxx.html
as opposed to what I keep getting:
/var/www/yyy/xxx/filefromfolderxxx.html
Any help would be greatly appreciated.
Try this:
cd /var/www/xxx
for a in * ; do ln -s /var/www/xxx/$a /var/www/yyy/$a ; done
This will symlink all the files one-by-one.
It's a bit messy, though. If you have multiple sites sitting on the same codebase but requiring different configuration files, you should really teach your framework how co-ordinate that for you. It's not really difficult, but does require more thinking than I can spare for this reply, I'm sorry.
Just use
ln -s /var/www/xxx/* /var/www/yyy
This tells ln: create a symlink for each file in xxx in the folder yyy. No need for for loops.

Resources