Move files from one location to another in Linux using Symbolic link - linux

I would like to know is it possible through symbolic (soft) link to move files from one location (A) to another (B) when files are getting created in the A location.

So you have some program creating files in some directory (e.g. in /fixed/location/), and you want the data to be elsewhere (e.g /data/dir/somefile.txt...)
If you know in advance the name of the created files, you could make them symbolic links before starting the program:
ln -s /data/dir/somefile.txt /fixed/location/file.txt
and if you create that symbolic link before running the program, it will write the data into /data/dir/somefile.txt even if that file does not exist (but the directory /data/dir should exist when you type that ln -s)
Another (Linux specific) possibility is to make a bind mount. If e.g. you want the data inside /usr/src/ to reside in /home/Src/ you could first mkdir /home/Src then e.g. add the following line in your /etc/fstab file:
/usr/src /home/Src none bind 0 0
I'm actually doing that (on /usr/src and /usr/local) for every Linux system where /home/ is a different filesystem, because I want them to be in the same backed up file system as /home/

Related

Odd behaviour of pwd with symlinks in terminal tabs

If I create a symlink through
ln -s /path/to/linked/dir current/path/link_name
and change the directory to current/path/link_name via
cd link_name
then I can check where I am using pwd-command. The output will be
current/path/link_name
But if I use some terminal emulator, such as terminator, konsole or others, I can split the tab or create a new tab in the same directory. The output of the pwd-command in the newly created tab will be
/path/to/linked/dir
In many cases, this is not convenient. Does anybody know how to change this behaviour in some terminal emulator(s)?
P.S. I also noticed that the output of ls typed from /current/path/link_name is the same as the output of ls typed from /path/to/linked/dir.
You can't. The reason is that you lose the information on how did you get there after the system call has executed. Some terminal emulators and mainly the bash(1) shell try to remember this, and implement pwd as an internal command, to cope with this scenarios. But in general if you try
/bin/pwd
You'll discover that all the information about how did you get to that final directory was lost in the course of time.
Ask yourself how can the /bin/pwd work and how can it determine the directory you are on, and you'll answer yourself the question:
The system maintains a current directory (the pwd command inherits this from its parent shell) in the system data for each process, but to save resources, it only stores the inode number of the directory that is actually your current directory (not actually, it maintains a reference to the in-core inode structure). It doesn't store the path you used to locate it, and it stores that info only to be able to get a starting point when you ask for a relative path when opening a file. The problem is the same as determining which directory a multiple linked file belongs to... no parent directory is stored for a file, as it can be in multiple directories linking to it all at the same time... this is also true for directories, but they have an .. entry inside themselves that links to their parents (their true parents, as one directory is now allowed to belong to different directories by means on normal links, this is forbidden by system, and ensured by the mkdir(2) system call) The pwd(1) commands uses precisely these links to find the parent directory (and then find the current dir in the parent directory, by searching for the inode number of the current directory on it), until this algorithm leads to the same inode (the root directory has this special characteristic, its .. entry points again to itself) so it stops going up. pwd can only work because it is following directories, and never files.
Terminator 1.90 does what you want. In an example session:
$ cd -- "$(mktemp --directory)"
$ mkdir a
$ ln -s a b
$ cd b
Press Ctrl-Shift-e (or o, or t). At this point I'm still in b.

will coping files recursively from one directory to another lead to changes in one directory reflect in another directory files also?

If I copy files from one directory to another directory:
Will their inode numbers also change?
Changes in file of one directory, will it reflect in same file of another directory also?
When I use command like:
cp -r dir1/ dir2/
With a simple copy the file system handle the copied files as newly created ones, therefore assining new inodes to them.
Any change made in the origin wouldn't change the copys. This only happens when you create symbolic or hard links between files.
You can check the inodes of your files with "ls -i filename".

Symbolic links to folders whose parent directory has no execute permission

I am trying to do a soft link from one directory to another, the directory I am trying to access I have read and execute. However, its parent directory I do NOT have execute permissions.
Is there a way to do a soft link, to my desired directory without giving me execute permission to the parent directory?
Below is the code I used:
ln -s /home/dir1/dir2/desired_directory symbolic_link_name
the link just comes up as red with grey background.
Thank you.
Although this is not possible with symlinks, you could do it with mount --bind. Note that if the whole point is to circumvent security, then this is probably a very bad idea.
Your command would be
mount --bind /home/dir1/dir2/desired_directory mount_dir
There are a few issues to be aware of:
The target directory mount_dir must exist before (same as any mount point)
Root access is required to execute the mount commmand
The created "link" will not persist after a reboot unless a corresponding line is added to /etc/fstab
If the origin directory contains mounted file systems, these will not be transferred to the target. The mount points will appear as empty directories.
Using mount --bind may be considered bad practice because most programs are not aware that the "link" is not a standard directory. For instance it allows the creation of loops in the directory tree which make any tree parsing application (think "ls -R") enter a possibly infinite loop.
It may be hazardous when combined with recursive delete operations. See for instance Yet another warning about mount --bind and rm -rf.
Symbolic links are not a way to circumvent permissions set on their targets. No, there is no way to do what you want. If it was possible it would be a serious security issue.

symlinking and running an installation command

In the installation guide of some soft, user is told to run this
sudo ln -s /opt/local/somesoft/somsoft* /opt/local/bin
Is this command dangerous ? Should /opt/local/bin be prevented from calling something else tha n itself ?
This command does few things
sudo gives root permissions to the 'ln' binary
ln is instructed to go through all files matching pattern /opt/local/somesoft/somsoft*
for every such file it tries to create symbolic link in /opt/local/bin directory
this created symbolic link will have the same name as the file just being processed
Your first question is, is it dangerous? Most probably not, there are few things which might go wrong
your $PATH environment contains some strange directory, so instead of calling /usr/bin/ln (as was the original intention I believe) you wold be tricked into calling some different executable. For example if your PATH=.:/tmp:/usr/bin, 'ln' is first searched in your current directory, then in /tmp and then in /usr/bin. And it's called with superuser permissions ...
there are no such files as /opt/local/somesoft/somsoft* . In such case ln will create symbolic link '/opt/local/bin/somsoft*' (including the star in it's name). That's probably not what you wanted
/opt/local/bin already contains the files with the same names as /opt/local/somesoft/somsoft* . In such case ln will not create new files there (is it good or bad? that is the question)
You don't have /opt/local/bin . In such cases there are several ways of how the command fails (depending whether you have /opt/local directory and how many files match the pattern /opt/local/somesoft/somsoft*)
Your second question does not make much sense. /opt/local/bin is a directory, and directory can't "call" anything. So it can't be prevented to do so. If you ask whether the symbolic links should be created there, I would say why not. The whole idea behind the command is to
install somesoft into special directory so that you won't pollute your /usr/bin or any other common directory
to be able to run the commands without the need of specifying every time full path /opt/local/somesoft/somsoft... you may want to create symbolic links in /opt/local/bin. And make sure that your /opt/local/bin is in your directory.

A confusion in APUE2(about symbolic link in UNIX)

The original text is below.It is in Section 4.22
The program in Figure 4.24 changes to a specific directory and then calls getcwd to print the working directory. If we run the program, we get
$ ./a.out
cwd = /var/spool/uucppublic
$ ls -l /usr/spool
lrwxrwxrwx 1 root 12 Jan 31 07:57 /usr/spool -> ../var/spool
Note that chdir follows the symbolic link as we expect it to, from Figure 4.17 .but when it goes up the directory tree, getcwd has no idea when it hits the /var/spool directory that it is pointed to by the symbolic link /usr/spool. This is a characteristic of symbolic links.
What does the author really mean by saying that the program hits the /var/spool?
What is the characteristic of symbolic links pointed out by the author?
I did not really understand.
Note that some shells, notably bash, keep track of whether you arrived at a given directory by chasing a symbolic link, and print the current directory accordingly. At least bash has options to cd to do a physical or logical change directory:
cd [-L|-P] [dir]
Change the current directory to dir. The variable HOME is the default dir. [...] 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 argument of - is equivalent to $OLDPWD. If a non-empty directory name from CDPATH is used, or if - is the first argument, and the directory change is successful, the absolute pathname of the new working directory is written to the standard output. The return value is true if the directory was successfully changed; false otherwise.
In the scenario shown, where /usr/spool is a symbolic link to /var/spool, then:
$ pwd
/
$ cd /usr/spool/uucppublic
/usr/spool/uucppublic
$ cd -L ..
/usr/spool
$ cd /usr/spool/uucppublic
/usr/spool/uucppublic
$ cd -P ..
/var/spool
$
For most people, a plain cd .. would do the same as cd -L ... You can choose to have bash do the same as cd -P .. instead if you prefer (using set -P or set -L).
The process of finding the pathname of the current directory should be understood too. Logically, the process (kernel) opens the current directory (.) and reads the inode number (and device number). It then opens the parent directory (..), and reads entries from that until it finds one with the matching inode number (and device number). This then gives it the last component of the pathname. It can now repeat the process, finding the the inode number of the next directory up, and opening its parent directory (../..), etc, until it reaches the root directory (where the inode number for both . and .. is the same, and the value is conventionally 2). Note that this even works across mount points. Beware of auto-mounted remote (NFS) file systems, though; it can be really slow if you scan through a directory containing several hundred automounted machines - as the naïve search outline above mounts all the machines until it finds the correct one. So, actual getcwd() functions are cleverer than this, but it explains how the path of the current directory is found. And it also shows why the process will not encounter /usr/spool when evaluating the directory under /var/spool/uucppublic - it simply never opens the /usr directory.
Note that the realpath() function (system call) takes a name possibly referencing symlinks and resolves it to a name that contains no symlinks at all. Passed /usr/spool/uucppublic, it would return /var/spool/uucppublic, for example.
Expanding on what #undor_gongor wrote:
Each process has a current working directory. It's not stored as the path name of the directory; it's a reference to the directory itself.
If it were stored as a path name, then the getcwd() function's job would be trivial: just print the path name. Instead, it has to readi the current directory, open its .. entry, then open that directory's .. entry, and so forth until it reaches the root (i.e., a directory whose .. entry points to the directory itself). It builds up the full path of the current directory in reverse order as it does this.
Since .. can't be a symlink, this process is not affected by symbolic links.
(Shells might have a $PWD or $CWD variable, or a pwd built-in, that is affected by symlinks; these typically work by remembering the string that was passed to cd or pushd.)
Assume you have a symlink /usr/spool pointing to /var/spool.
It says if you follow that symlink (e.g. cd /usr/spool), you end up in the pointed-to directory (/var/spool). Then, the information that you followed a symlink is lost. You are in /var/spool as if you had done cd /var/spool directly.
A further cd .. brings you to /var (as opposed to /usr).
UPDATE:
As pointed out by Keith Thompson and Jonathan Leffler, there are some shells that do remember the path you followed (i.e. /usr/spool). In such shells, cd ..
would go to /usr/. However, programs started from such a shell would still see /var/spool as the working directory.
This is probably the reason the author let you write a program for displaying cwd (to work-around such shells' internals).

Resources