linux: what is the difference between these two symbolic link commands - linux

I am trying to create a symbolic link on the server with the command ln -s,
Option 1:
ln -s /home/thejobco/public_html/JCCore/ajax_search /home/thejobco/public_html/demo/typo3conf/ext/
result 1:
ajax_search -> /home/thejobco/public_html/JCCore/ajax_search
Option 2:
ln -s /home/thejobco/public_html/JCCore/ajax_search/ /home/thejobco/public_html/demo/typo3conf/ext/
result 2:
ajax_search -> /home/thejobco/public_html/JCCore/ajax_search/
Question:
I want to know if the above two options are the same, or there is different between them? Option 1 does not have /, option 2 has /, but both of them work well, so just wonder which is the standard way?

A symbolic link is implemented as a file containing the name of the target.
There is a minor difference, as you've seen: one of the symlinks has a trailing /, and the other doesn't. You can see the difference in the output of ls -l; on a lower level, this shows up as a difference in the path returned by the readlink() system call.
But there should be no functional difference between them -- as long as the target is a directory. Either can be used to access the linked directory.
For a target that's not a directory, this:
ln -s /etc/motd good_link
ln -s /etc/motd/ bad_link
will result in good_link being a valid way to access /etc/motd, and bad_link resulting in a not a directory error.

Related

softlink to binary always use home folder path (instead of current folder)

kdevelop provides this AppImage binary:
wget -O KDevelop.AppImage https://download.kde.org/stable/kdevelop/5.1.1/bin/linux/KDevelop-5.1.1-x86_64.AppImage
chmod +x KDevelop.AppImage
./KDevelop.AppImage
It works well. So I want to make a soft link called kd to that binary in /usr/bin, eg:
/usr/bin/sudo ln -s KDevelop-5.1.1-x86_64.AppImage kd
Now if I run kd file1, I'd expect that it would open a file name file1 in the current folder, but it always tries to open a file name file1 in my home folder - which is not where it should be.
Is there some way to fix this issue?
Some possible causes:
The application always assumes that you want to open files in your home directory, effectively or literally prepending $HOME to the path. This would be a bug in any *nix program, and should be reported.
The application behaves differently when $(basename "$0") is not KDevelop.AppImage (what #Scheff said).
You are actually running a different kd.
Possible workarounds/investigations:
Pass the full path to the file on the command line. If it tries to open /home/you//full/path/you/provided it is obviously buggy, and you have a test case. If it does not, then there might be some gotcha to what your $PWD actually is. Try checking its value before running.
Symlink with the same name, using sudo ln -s KDevelop-5.1.1-x86_64.AppImage /usr/bin, and try running that. If it behaves the same, you've at least proven that the symlink is not the problem.
Run type -a kd and verify that your /usr/bin/kd comes up first. If not there might be an alias or shell built-in which takes precedence.
That said, what is the actual error message?

Symlinking doesn't work in Ubuntu

I tried ln -s ./storage/profile_pictures/* ./public/profile_pictures/ but that renders my images useless. In my Finder, it says image.png (alias), but in preview it doesn't show the picture, just a white page icon.
How do I fix this?
As morido said, you want public/profile_pictures to be a symlink to the directory storage/profile_pictures. So don't use ./storage/profile_pictures/*, because the shell will expand that to a list of all files in ./storage/profile_pictures/.
Secondly, you're using a relative path:
ln -s ./storage/profile_pictures ./public/profile_pictures
says "make a symlink in ./public/profile_pictures that points to ./storage/profile_pictures". The first argument is relative to the second one. That is, you'd wind up with ./public/profile_pictures/profile_pictures which points to the directory ./public/profile_pictures/storage/profile_pictures, which presumably doesn't exist.
The easiest way to do this is likely
cd public
ln -s ../storage/profile_pictures profile_pictures
You almost got it. The following should work if you want to make a symbolic link from storage/profile_pictures/ to public/profile_pictures/:
ln -s storage/profile_pictures public/profile_pictures
Note that public/profile_pictures must not yet exist.
This link will allow you to access a picture 1.jpg both as storage/profile_pictures/1.jpg and as public/profile_pictures/1.jpg

Behavior of cd/bash on symbolic links

Assume I have the folders ~/a/b in my home folder, and the folder b contains
a symbolic link to '..' named 'symlink'. Then I perform the following actions in
bash:
hm#mach:~$ cd a/b/symlink
hm#mach:~/a/b/symlink$ pwd -P
/home/hm/a
hm#mach:~/a/b/symlink$ cd ..
hm#mach:~/a/b$ pwd -P
/home/hm/a/b
pwd -P prints the current working directory, dereferencing all symbolic links.
Why is the working directory /home/hm/a/b at the end, and not /home/hm?
According to help cd,
Options:
-L force symbolic links to be followed: resolve symbolic
links in DIR after processing instances of `..'
-P use the physical directory structure without following
symbolic links: resolve symbolic links in DIR before
processing instances of `..'
In other words, -L means using the logical structure, whereas -P uses the actually physical directory structure.
The logical structure is like this,
$ tree a
a
└── b
└── symlink -> ..
The actual physical structure when you go to a/b/symlink is,
a
If you want to use the real .., then you must also use cd -P:
The -P option says to use the physical directory
structure instead of following symbolic links (see
also the -P option to the set builtin command);
the -L option forces symbolic links to be followed.
An example,
$ cd
$ cd a/b/symlink # physical location is at a/
$ cd .. # now is at a/b
$ cd symlink # goes back to a/b/symlink
$ cd -P .. # follow physical path (resolve all symlinks)
$ pwd -P # -P is optional here to show effect of cd ..
/home/sarnold
$
bash keeps track of the logical current directory path, as shown in your prompt, and interprets things like cd .. according to that. This makes things a little more consistent if you only use such paths in cd (or pushd), at the cost of unexpected things happening if you then expect the same thing to happen with paths in command arguments (or inside commands; emacs and vim have their own configurable rules for symlink handling, but most commands rely on the kernel to deal with it).

symbolic link without expanding $HOME or "~"?

the basic idea is that I want to link to path that's relative to $HOME, rather than explicitly expand the $HOME variable, as I want to make sure the link works on multiple machines, e.g.,
when I do
ln -s ~/data datalnk
I want it to be directed to directory /home/user/data on one machine which has a user $HOME of /home/user, and to /home/machine/user/data on another machine which has a user $HOME of /home/machine/user/data.
I cannot create a symbolic link on the second machine using
ln -s /home/machine/user /home/user
because I don't have the permission to do that, and I cannot link relative paths as the two machines have different hierarchies of directories.
anyideas on possible ways to fix or circumvent this?
EDIT:
what I am really trying to accompanish is to make the same link work on two macihnes, where the targets have the same directories in terms of their relative path to $/HOME only, not their absolute path, and not their relative path to the link either.
tl,dr it won't work
You can use an escaping mechanism such as single-quotes to get the ~ into the symbolic link:
> cd ~
> echo hello > a
> ln -s '~/a' b
However, ~ is a shell expansion and is not understood by the filesystem (actually, to the filesystem it's "just another character"). This is a good thing -- want the file-system layer to know about environment variables, as ~ is generally determined by $HOME?
> ls -l b
lrwxrwxrwx 1 root root 3 Oct 27 17:39 b -> ~/a
> ls b
ls: b: No such file or directory
You could still "manually" look at said symbolic link entries (as done with ls -l), but that would have to be done in a non-transparent fashion by a program (think of a ".LNK" in Windows). As can be seen, the filesystem just doesn't understand ~.
Happy sh'ing.
First of all: It can't be done directly. Symbolic links are plain text files, no extensions are performed. If you can't formulate a fixed relative or absolute path to the place you are referring, you can't symbolically link to it.
You can build a script to put links to appropriate directories in appropriate places, but the best way depends on your application.
The only way to make symlinks dynamic in this way is to use a relative path instead of an absolute path. In other words, don't start your path with /.
For example:
cd
ln -s data datalnk
At runtime your app or script will need to refer to ~/datalnk or $HOME/datalnk.
You haven't really said what you're trying to accomplish, so I can't really tell whether I'm solving your problem or suggesting that you need to go at it a different way.

How can I symlink a file in Linux? [closed]

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

Resources