Symlink broken right after creation - bash

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 :)

Related

Symlink not being created

I'm running Fedora on a laptop with a small SSD and large HDD. I've got the OS installed on the SSD and my data on the HDD.
All my files are located at /run/media/kennedy/data/Kennedy
What I had before (and want again) is a symlink from /home/kennedy to that location. That way I'm not messing with actual /home, but when I am in /home as normal user, all my things are easily accessed and stored with plenty of space. Right now /home/kennedy has the standard directories; desktop, documents, downloads, and so forth. No files worth worrying about.
So I opened a shell, logged in as su, and entered
ln -s /home/kennedy /run/media/kennedy/data/Kennedy
expecting that when I cd /home/kennedy and ls, I would see all my lovelies. Instead, I see that standard folders and nothing more. Whisky Tango Foxtrot, over.
edit to add: I'm pretty sure the permissions are right, but only pretty sure. How do I check and correct that (if off)?
You have to reverse the arguments:
ln -s /run/media/kennedy/data/Kennedy /home/kennedy
This will:
run successfully if /home/kennedy doesn't exist (kennedy would be the new symlink)
fail if /home/kennedy exists and it is not a directory (symlink or a regular file); need add -f flag in such a case - ls -sf ...
if /home/kennedy is a directory, then the symlink will be created as /home/kennedy/kennedy
See this related post: How to symlink a file in Linux?
You have the command backwards, it should be:
ln -s /run/media/kennedy/data/Kennedy kennedy
Invoke the command while you are in your /home directory, then you should be set.

Broken symbolic link [duplicate]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
I want to make a symbolic link in Linux. I have written this Bash command where the first path is the folder I want link into and the second path is the compiled source.
ln -s '+basebuild+'/IpDome-kernel/kernel /home/build/sandbox/gen2/basebuild/IpDome-kernel/kernal
Is this correct?
To create a new symlink (will fail if symlink exists already):
ln -s /path/to/file /path/to/symlink
To create or update a symlink:
ln -sf /path/to/file /path/to/symlink
ln -s TARGET LINK_NAME
Where the -s makes it symbolic.
ln -s EXISTING_FILE_OR_DIRECTORY SYMLINK_NAME
ln -s target linkName
You can have a look at the man page here:
http://linux.die.net/man/1/ln
(Because an ASCII picture is worth a thousand characters.)
An arrow may be a helpful mnemonic, especially since that's almost exactly how it looks in Emacs' dired.
And big picture so you don't get it confused with the Windows' version
Linux:
ln -s target <- linkName
Windows:
mklink linkName -> target
You could also look at these as
ln -s "to-here" <- "from-here"
mklink "from-here" -> "to-here"
The from-here should not exist yet, it is to be created, while the to-here should already exist (IIRC).
(I always get mixed up on whether various commands and arguments should involve a pre-existing location, or one to be made.)
EDIT: It's still sinking in slowly for me; I have another way I've written in my notes.
ln -s (target exists) (link is made)
mklink (link is made) (target exists)
ln -s source_file target_file
http://unixhelp.ed.ac.uk/CGI/man-cgi?ln
To the original question:
'ln -s '+basebuild+'/IpDome-kernel/kernel /home/build/sandbox/gen2/basebuild/IpDome-kernel/kernal'
This will indeed create a symbolic link (-s) from the file/directory:
<basebuild>/IpDome-kernel/kernel
to your new link
/home/build/sandbox/gen2/basebuild/IpDome-kernel/kernal
Here's a few ways to help you remember:
First, there's the man page for ln. You can access this via searching "man ln" in google, or just open a terminal window and type man ln and you'll get the same information. The man page clearly states:
ln [OPTION]... [-T] TARGET LINK_NAME (1st form)
If having to search or read through a man page every time isn't for you, maybe you'll have an easier time remembering that all nix commands work the same way:
cp /file/that/exists /location/for/new/file
mv /file/that/exists /location/its/moving/to
ln /file/that/exists /the/new/link
cp copies a file that currently exists (the first argument) to a new file (the second argument).
mv moves a file that currently exists (the first argument) to a new place (the second argument)
Likewise ln links a file that currently exists (the first argument) to a new link (the second argument)*
The final option I would like to suggest is you can create your own man pages that are easy to read and easy (for you) to find/remember. Just make a simple shell script that gives you the hint you need. For example♦:
In your .bash_aliases file you can place something like:
commandsfx() {
echo "Symlink: ln -s /path/to/file /path/to/symlink"
echo "Copy: cp /file/to/copy /destination/to/send/copy"
}
alias 'cmds'=commandsfx
Then when you need it, from the command line just type cmds and you'll get back the proper syntax in a way you can quickly read and understand it. You can make these functions as advanced as you'd like to get what what information you need, it's up to you. You could even make them interactive so you just have to follow the prompts.. something like:
makesymlink() {
echo "Symlink name:"
read sym
echo "File to link to:"
read fil
ln -s $fil $sym
}
alias 'symlink'=makesymlink
* - well obviously they can all take different parameters and do different things and can work on files as well as directories... but the premise is the same
♦ - examples using the bash shell
ln [-Ffhinsv] source_file [target_file]
link, ln -- make links
-s Create a symbolic link.
A symbolic link contains the name of the file to which it is linked.
An ln command appeared in Version 1 AT&T UNIX.
Creating Symbolic links or Soft-links on Linux:
Open Bash prompt and type the below mentioned command to make a symbolic link to your file:
A) Goto the folder where you want to create a soft link and typeout the command as mentioned below:
$ ln -s (path-to-file) (symbolic-link-to-file)
$ ln -s /home/user/file new-file
B) Goto your new-file name path and type:
$ ls -lrt (To see if the new-file is linked to the file or not)
Example:
user#user-DT:[~/Desktop/soft]# ln -s /home/user/Desktop/soft/File_B /home/user/Desktop/soft/File_C
user#user-DT:[~/Desktop/soft]# ls -lrt
total 0
-rw-rw-r-- 1 user user 0 Dec 27 16:51 File_B
-rw-rw-r-- 1 user user 0 Dec 27 16:51 File_A
lrwxrwxrwx 1 user user 31 Dec 27 16:53 File_C -> /home/user/Desktop/soft/File_B
Note: Where, File_C -> /home/user/Desktop/soft/File_B Means, File_C is symbolically linked to File_B
ln -s sourcepath linkpathname
Note:
-s makes symbolic links instead of hard links
This is Stack Overflow so I assume you want code:
All following code assumes that you want to create a symbolic link named /tmp/link that links to /tmp/realfile.
CAUTION: Although this code checks for errors, it does NOT check if /tmp/realfile actually exists ! This is because a dead link is still valid and depending on your code you might (rarely) want to create the link before the real file.
Shell (bash, zsh, ...)
#!/bin/sh
ln -s /tmp/realfile /tmp/link
Real simple, just like you would do it on the command line (which is the shell). All error handling is done by the shell interpreter. This code assumes that you have a working shell interpreter at /bin/sh .
If needed you could still implement your own error handling by using the $? variable which will only be set to 0 if the link was successfully created.
C and C++
#include <unistd.h>
#include <stdio.h>
int main () {
if( symlink("/tmp/realfile", "/tmp/link") != 0 )
perror("Can't create the symlink");
}
symlink only returns 0 when the link can be created. In other cases I'm using perror to tell more about the problem.
Perl
#!/usr/bin/perl
if( symlink("/tmp/realfile", "/tmp/link") != 1) {
print STDERR "Can't create the symlink: $!\n"
}
This code assumes you have a perl 5 interpreter at /usr/bin/perl. symlink only returns 1 if the link can be created. In other cases I'm printing the failure reason to the standard error output.
If you are in the directory where you want to create symlink, then ignore second path.
cd myfolder
ln -s target
It will create symlink of target inside myfolder.
General syntax
ln -s TARGET LINK_NAME
I'd like to present a plainer-English version of the descriptions already presented.
ln -s /path-text/of-symbolic-link /path/to/file-to-hold-that-text
The "ln" command creates a link-FILE, and the "-s" specifies that the type of link will be symbolic. An example of a symbolic-link file can be found in a WINE installation (using "ls -la" to show one line of the directory contents):
lrwxrwxrwx 1 me power 11 Jan 1 00:01 a: -> /mnt/floppy
Standard file-info stuff is at left (although note the first character is an "l" for "link"); the file-name is "a:" and the "->" also indicates the file is a link. It basically tells WINE how Windows "Drive A:" is to be associated with a floppy drive in Linux. To actually create a symbolic link SIMILAR to that (in current directory, and to actually do this for WINE is more complicated; use the "winecfg" utility):
ln -s /mnt/floppy a: //will not work if file a: already exists
To create a symbolic link /soft link, use:
ln -s {source-filename} {symbolic-filename}
e.g.:
ln -s file1 link1
Links are basically of two types:
Symbolic links (soft): link to a symbolic path indicating the abstract location of another file
Hard links: link to the specific location of physical data.
Example 1:
ln /root/file1 /root/file2
The above is an example of a hard link where you can have a copy of your physical data.
Example 2:
ln -s /path/to/file1.txt /path/to/file2.txt
The above command will create a symbolic link to file1.txt.
If you delete a source file then you won't have anything to the destination in soft.
When you do:
ls -lai
You'll see that there is a different inode number for the symlinks.
For more details, you can read the man page of ln on your Linux OS.
There are two types of links:
symbolic links: Refer to a symbolic path indicating the abstract location of another file
hard links: Refer to the specific location of physical data.
In your case symlinks:
ln -s source target
you can refer to http://man7.org/linux/man-pages/man7/symlink.7.html
you can create too hard links
A hard link to a file is indistinguishable from the original directory entry; any changes to a file are effectively independent of the name used to reference the file. Hard links may not normally refer to directories and may not span file systems.
ln source link
I find a bit confusing the terminologies "target" and "directory" in the man information.
The target is the folder that we are symlinking to and the directory the actual symlink (not the directory that you will be symlinking to), if anyone is experiencing the same confusion, don't feel alone.
This is my interpretation of creating a Symlink (in linux):
ln -s /FULL/PATH/FOLDER-OR-FILE-SYMLINKING-TO NAME-OF-YOUR-SYMLINK
You can navigate to the folder where you want to create the symlink and run the command or specify the FULL PATH for your symlink instead of NAME-OF-YOUR-SYMLINK.
cd /FULL/PATH/TO/MY-SYMLINK-PARENT-FOLDER
ln -s /FULL/PATH/FOLDER-OR-FILE-SYMLINKING-TO NAME-OF-YOUR-SYMLINK
OR
ln -s /FULL/PATH/FOLDER-OR-FILE-SYMLINKING-TO /FULL/PATH/TO/MY-SYMLINK-PARENT-FOLDER/NAME-OF-YOUR-SYMLINK
I hope this helps to those (still) slighly confused.
How to create symlink in vagrant.
Steps:
In vagrant file create a synced folder. e.g config.vm.synced_folder "F:/Sunburst/source/sunburst/lms", "/source"
F:/Sunburst/source/sunburst/lms :- where the source code, /source :- directory path inside the vagrant
Vagrant up and type vagrant ssh and go to source directory e.g cd source
Verify your source code folder structure is available in the source directory. e.g /source/local
Then go to the guest machine directory where the files which are associate with the browser. After get backup of the file. e.g sudo mv local local_bk
Then create symlink e.g sudo ln -s /source/local local. local mean link-name (folder name in guest machine which you are going to link)
if you need to remove the symlink :- Type sudo rm local

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).

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.

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