symbolic link : confused about what it creates - symlink

I am confused about the command "ln -s".
When I do:
sudo ln -s /projects/MyProject ~/project1/code
This creates a "MyProject" folder link inside my "~/project1/code" folder.
I was hoping to have the same content on /projects/MyProject and ~/project1/code, not finding a subfolder "Myproject".
Can I do what I want with ln -s or should I look at something else?
Thanks

A symbolic link is effectively a pointer to some other file. It is not entirely clear what you want, but the following will create a symbolic link called MyProject in the ~/project1 directory:
sudo ln -s /projects/MyProject ~/project1/
That is, there will exist a directory ~/project1/MyProject that contains all the same files as in /projects/MyProject. If you update or add files to ~/project1/MyProject, they will be updated or added to /projects/MyProject.
Alternatively, if you want to keep track of just the files in /projects/MyProject, then you can do the following:
sudo ln -s /projects/MyProject/* ~/project1/code`
This will create the directory ~/project1/code which will contain symbolic links to all the files in /projects/MyProject. New files added to ~/project1/code will not be added to projects/MyProject, however.
EDIT
Alternatively, if you go into the ~/project1 directory and then type
sudo ln -s /projects/MyProject code
then that will create a symbolic link called code in the ~/project1 directory, which is itself a link to /projects/MyProject.

Related

Cannot run ctags after executing "ln -s /usr/bin/ctags-exuberant"

By mistake I have executed the following command on my redhat office machine and now I cannot run ctags -R * any more.
ln -s /usr/bin/ctags-exuberant
Hope following info helps,
[ypp:~]$ ls /usr/bin/ctags-exuberant
[ypp:~]$ ls: /usr/bin/ctags-exuberant: No such file or directory
[ypp:~]$ unlink /usr/bin/ctags-exuberant
unlink: cannot unlink /usr/bin/ctags-exuberant': No such file or directory
[ypp:~]$ which ctags
alias ctags='/usr/bin/ctags'
/usr/bin/ctags
[ypp:~]$ ln -s /usr/bin/ctags-exuberant /usr/bin/ctags
ln: creating symbolic link '/usr/bin/ctags' to '/usr/bin/ctags-exuberant': File exists
[ypp:~]$ ln -s /usr/local/bin/ctags /usr/bin/ctags-exuberant
ln: creating symbolic link ,/usr/bin/ctags-exuberant' to '/usr/local/bin/ctags': Permission denied
So far I have tried,
[ypp:~]$ rm /usr/bin/ctags-exuberant
/bin/rm: cannot lstat /usr/bin/ctags-exuberant': No such file or directory
[ypp:~]$ rm -i /usr/bin/ctags-exuberant
/bin/rm: cannot lstat /usr/bin/ctags-exuberant': No such file or directory
[ypp:~]$ unlink /usr/bin/ctags
unlink: cannot unlink /usr/bin/ctags': Permission denied
Please tell me how do I get my ctags working back to normal,
I don't have superuser privilege also.
According the manpage, ln creates a link to file TARGET with the name LINKNAME. If LINKNAME is omitted, as was your case, a link to TARGET is created in the current directory, using the name of TARGET as the LINKNAME. As a result, when you executed ln -s /usr/bin/ctags-exuberant a symbolic link (sometimes called soft link) named ctags-exuberant would have been created in your present working directory pointed at /usr/bin/ctags-exuberant.
There seems to be more at play than what you have shared with us here. Simply creating a link to ctags-exuberant in any directory should not have resulted in the changes you are experiencing. Where there other changes made to your path?
If, somehow just creating the link has caused all your troubles, then you need to focus on finding the resulting link and removing it. If you don't know what directory it was created in, you could find it via the following:
find / -type l -name 'ctags-exuberant' 2>/dev/null
Once it is found, remove it and see if that fixes your problems. Let us know what you find.
Else, you might do better to try the wise minds over at https://unix.stackexchange.com/

symbolic link can only be created from parent to child under FreeBSD?

https://www.youtube.com/watch?v=-XosJtC0vyA
In the current directory(test), I have used
echo date > date.sh ; chmod u+x date.sh
to create date.sh and make it executable.
Then I used
ln -s date.sh ../date.sh.sym1
ln -s ./date.sh ../date.sh.sym2
to create two symbolic links in the parent directory from which I typed
./date.sh.sym1
./date.sh.sym2
The result was that both showed command not found.
Then in the parent directory, I used
ln -s test/date.sh date.sh.sym3
to create another symlink. This time it becomes executable after I typed
./date.sh.sym3
Is it because symlink can only be created from parent to child ? (FreeBSD 10.2)
The user in the video typed the ln commands incorrectly. The first parameter to ln is the target (what you're linking to) the second paramter is where the place the link. When you do ln -s date.sh ../date.sh.sym1 you're placing a symlink in the parent directory to something in the current directory. The user in the video then changed directories to the parent directory. From that frame of reference the OS was expecting something called date.sh in the current directory. Hence the command not found errors.
The second ln, ln -s test/date.sh date.sh.sym3 created a link to test/date.sh. That path (test/date.sh) could be resolved, which is why it ran.

Can't get symlinks to work for dotfiles

So I'm trying to create symlinks for my dotfiles (that way I can have a centralized dotfiles repository) but everytime I do this, iTerm won't read the symlinked files. Basically meaning I won't have access to any aliases or other configurations.
I believe I'm correctly symlinking the files by putting the link in the home directory and the actual file in the repository location with:
ln -s ~/.dot_file ~/Google\ Drive/Developer/git\ repositories/dotfiles/dot_file
I've also tried doing it the reverse way but then the repository doesn't have the contents of the file in the link. aka:
touch ~/Google\ Drive/Developer/git\ repositories/dotfiles/dot_file
mv .dot_file ~/Google\ Drive/Developer/git\ repositories/dotfiles/dot_file
cd ~/Google\ Drive/Developer/git\ repositories/dotfiles
ln -s dot_file ~/.dot_file
I've referenced these articles.
How to use Github to manage dotfiles?
Using bash to automate dotfiles
Using find on subdirectories and create symlinks to all files
Symlinks not working when link is made in another directory?
Help please! :)
Your first example links the wrong way (it's ln -s source target, just like cp and mv).
In your second example, you create an invalid relative link.
You can use ls -l yourfile to see whether a file is a symlink, and see where it points.
What you'll want to do is:
cd ~
ln -s "Google Drive/Developer/git repositories/dotfiles/dot_file" ".dot_file"
Before you start, make sure you don't have a ~/.dot_file, and make sure your Google Drive/Developer/git repositories/dotfiles/dot_file is a regular file with the contents you want (again, with ls -l).

Symlink broken right after creation

I downloaded the linux Tor Browser package, which is a self-contained folder. I made a symlink to the run script:
$ ln -s torbrowser/start-tor-browser ~/bin/torbrowser
However, the link was broken upon creation. All I did was run that command, nothing else, and it was broken. I did ls and got:
lrwxrwxrwx 1 synful synful 28 Jul 18 21:52 torbrowser -> torbrowser/start-tor-browser
...which is weird because torbrowser/start-tor-browser had 755 permissions. Also, I ran file:
$ file ~/bin/torbrowser
bin/torbrowser: broken symbolic link to `torbrowser/start-tor-browser'
I made a new bash script and a symlink to it to test this, and had no such problems. I'm not sure why it's only happening with start-tor-browser. It's got normal permissions and is just a normal bash script (even according to the file command).
...any ideas?
It's important to know that
ln -s SOURCE TARGET
create a symlink called TARGET which is symbolically linked to the string SOURCE. If SOURCE is a relative path (that is, it does not start with /), then it is interpreted relative to the directory that TARGET is in. If it is an absolute path, then it's an absolute path. If it is a string which could not be a path, or includes a non-existing path or file, or is otherwise not a valid path string, no matter. ln -s does not check that SOURCE exists or is even a valid path. You could store almost any shortish string you wanted in the dirent.
So when you do this:
$ ln -s torbrowser/start-tor-browser ~/bin/torbrowser
what you are doing is, roughly:
create a directory entry inside your bin subdirectory with name torbrowser.
Make that new directory entry a symbolic link (symlink) to the (relative) path torbrowser/start-tor-browser
The new symlink is a circular. ~/bin/torbrowser is linked to ~/bin/torbrowser/start-tor-browser, which means you have to follow the symlink in order to resolve the symlink. If you try to use it, you'll see:
$ cat ~/bin/torbrowser
cat: /home/joshlf13/bin/torbrowser: Too many levels of symbolic links
$
Sometimes -- often, even -- the ability to symlink to a relative path is extremely handy. A common use is getting rid of version numbers:
$ ln -s apps/my_fancy_app_v2.63.1 apps/my_fancy_app
Now, not only can I call my_fancy_app without remembering its version string, I can also move the entire folder elsewhere, without breaking the symlink:
$ mv apps /usr/local/apps
But other times -- as in your example, I think -- you need to symlink to an absolute path.
As for the permissions, symlinks always have permissions lrwxrwxrwx because the actual permissions used by file operations are the permissions on the real file. (You can think of that as meaning that anyone can follow the symlink, but that's not quite true: they'd also need read permissions for any directory they need to follow. More accurately, anyone who can see the symlink can see the name it points to, even if they have no access to the file with that name.
It is important that the TARGET you specify in
ln -s TARGET LINK_NAME
is full path of the file/directory.
I had this issue, in my case when I cd into target's directory and did
ln -s ./eclipse.ini ~/Desktop/eclipse1 resulted in broken link
But when I did this ln -s $(pwd)/eclipse.ini ~/Desktop/eclipse It worked!
the above usage given for ln:
ln -s SOURCE TARGET
is correct, but confusing when referred to the man page:
ln [OPTION]... [-T] TARGET LINK_NAME (1st form)
as 'TARGET' has different meaning
Note: this can also happen due to permissions
eg. if you try
sudo ln -s /home/somesuperuser/commonfile /home/somenormaluser/commonfile
this would not work, while
sudo mv /home/somesuperuser/commonfile /usr/share/commonfile
sudo ln -s /usr/share/commonfile /home/somenormaluser/commonfile
sudo ln -s /usr/share/commonfile /home/somesuperuser/commonfile
does work
I also struggled with this, I got lots of time Linux sym link broken after creating, but solution is simple - as mentioned by rici:
If SOURCE is a relative path (that is, it does not start with /), then
it is interpreted relative to the directory that TARGET is in.
In other words:
You have this dirs:
- my_directory
-- directory_1
- other_directory
-- *you want your directory_1 link here*
Easiest approach. Got to "other_directory". From there is simple:
ln -s ../my_directory/directory_1 directory_1
Done :)

How do I symlink the contents of the folder without including the actual folder?

I'm trying to symlink my Library/Fonts directory with a folder in my Dropbox, so that I don't have to keep installing and figuring out which machine has the fonts I need. When I try this:
ln -s Fonts/ ~/Library/Fonts
I get this error in return:
ln: /Users/Username/Library/Fonts/: File exists
I can't delete the folder because its required by the system and thus won't let you delete.
Delete the Fonts folder (obviously you'll want to move any files you want saved somewhere else) from your Dropbox directory and then type:
ln -s ~/Library/Fonts Fonts
Note that you do not want the trailing / for that last Fonts directory.
Edit to address comment:
You're right that this only links to one /Library/Fonts folder. You might try doing this on one machine and then on the other machine(s), try:
Turn off Dropbox
Save off the ~/Dropbox/Fonts folder
Perform the same symbolic link function as on the first computer (ln -s ~/Library/Fonts Fonts)
Copy over any fonts that might not be on this machine
Turn Dropbox back on
I have not tried this so I don't know if it will work, but it should do no harm.
The other alternative that definitely will work is to set up a cron job to copy any non-existent fonts in your ~/Library/Fonts folder to your ~/Dropbox/Fonts folder and vice-versa. If the symbolic link trick works, I think that would be preferred.
ln -s -F will force the creation of the link removing the original target before creating the link.
this method will only work if the target folder is already a symlink.
Using the ln that ships with OSX or BSD-derived unixes:
ln -s -h -F /source/folder/to/use /destination/folder/to/overwrite
the -h is key here. otherwise you'll end up with something like ~/Library/Fonts/Fonts because it traverses inside that folder. the -F alone wouldn't try to overwrite, since it wouldn't see a conflict once it got inside that folder.
relevant portions of ln manpage:
ln [-Ffhinsv] source_file ... target_dir
-s Create a symbolic link.
-h If the target_file or target_dir is a symbolic link, do not follow it.
This is most useful with the -f option, to replace a symlink which may
point to a directory.
-F If the target file already exists and is a directory, then remove it
so that the link may occur.
GNU coreutils ln users:
if you're using the GNU ln from the coreutils package (linux, brew, macports, etc.) use -T:
ln -sTf /source/folder/to/use /destination/folder/to/overwrite
additionally, with the GNU ln you can replace normal folders. look at its manpage for the -t option, use it to specify the parent of the target folder:
ln -sf -t /destination/folder/to/overwrite/.. /source/folder/to/use
the trailing /.. is needed to target creation inside the parent dir, leave it in place.

Resources