cp SOMEFILE .. copies to a different directory after cd'ing via a symbolic linkmv: cannot move (not a...
Function of the separated, individual solar cells on Telstar 1 and 2? Why were they "special"?
Is there anything in the universe that cannot be compressed?
Why would anyone say that it is problematic to notate this chant like this instead of using the standard notation for gregorian chant?
The Justice Thought & System & its Morals?
Can a country avoid prosecution for crimes against humanity by denying it happened?
Calculate Landau's function
Why wasn't Linda Hamilton in T3?
What is the definition of Product
Displaying Time in HH:MM Format
Can a system of three stars exist?
Could a simple hospital oxygen mask protect from aerosol poison?
Fishing from underwater domes
Using font to highlight a god's speech in dialogue
Why do we need explainable AI?
Does the telecom provider need physical access to the SIM card to clone it?
Get rows that exist exactly once per day for a given period
Why are CEOs generally fired rather being demoted?
What are ways to record who took the pictures if a camera is used by multiple people?
Pandas transform inconsistent behavior for list
How can I portray a character with no fear of death, without them sounding utterly bored?
To minimize the Hausdorff distance between convex polygonal regions
Am I required to correct my opponent's assumptions about my morph creatures?
Datasets of Large Molecules
What are the electrical characteristics of a PC gameport?
cp SOMEFILE .. copies to a different directory after cd'ing via a symbolic link
mv: cannot move (not a directory) from a symlink directorysymbolic link to a directory and relative pathSymbolic links with ls, mv: forcing the functions to utilize “logical” addresses (remembering the original path)cannot create symbolic link on CentOS 5.6 - File exists errorSymbolic Link with Existing Directorynemo: Context Menu Action Triggering a Script that Forces the Selected Symbolic Link to be RelativeCan GNU Stow use a stow directory that is a symbolic link?How can I determine last access of a symbolic link without updating it?What exactly is dot dot (..)? Why is its behavior different with symlinks?Execute symlink on different physical drivesSymbolic links do not allow SELinux type_transition
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
Consider the following setup:
~/Desktop/Public/subdir
~/Desktop/subdir --> ~/Desktop/Public/subdir (symbolic link)
Now I do:
cd ~/Desktop/subdir
Which leads me into the linked directory.
If I now issue the command:
cd ..
I will be moved back into the Desktop directory. This means the cd command is context sensitive - it remembers that I entered subdir via the symbolic link.
However, issuing the command
cp testfile ..
will copy testfile into Desktop/Public.
I prefer the behavior of cd over the (often unpredictable) behavior of cp. In any case, I wonder what is the reason for this difference in behavior? Just a legacy thing or is there a good reason?
shell symlink cp cd-command
add a comment |
Consider the following setup:
~/Desktop/Public/subdir
~/Desktop/subdir --> ~/Desktop/Public/subdir (symbolic link)
Now I do:
cd ~/Desktop/subdir
Which leads me into the linked directory.
If I now issue the command:
cd ..
I will be moved back into the Desktop directory. This means the cd command is context sensitive - it remembers that I entered subdir via the symbolic link.
However, issuing the command
cp testfile ..
will copy testfile into Desktop/Public.
I prefer the behavior of cd over the (often unpredictable) behavior of cp. In any case, I wonder what is the reason for this difference in behavior? Just a legacy thing or is there a good reason?
shell symlink cp cd-command
Btw., behaviour and behavior are both correct spellings.
– Konstantin Schubert
Jul 23 '13 at 10:38
add a comment |
Consider the following setup:
~/Desktop/Public/subdir
~/Desktop/subdir --> ~/Desktop/Public/subdir (symbolic link)
Now I do:
cd ~/Desktop/subdir
Which leads me into the linked directory.
If I now issue the command:
cd ..
I will be moved back into the Desktop directory. This means the cd command is context sensitive - it remembers that I entered subdir via the symbolic link.
However, issuing the command
cp testfile ..
will copy testfile into Desktop/Public.
I prefer the behavior of cd over the (often unpredictable) behavior of cp. In any case, I wonder what is the reason for this difference in behavior? Just a legacy thing or is there a good reason?
shell symlink cp cd-command
Consider the following setup:
~/Desktop/Public/subdir
~/Desktop/subdir --> ~/Desktop/Public/subdir (symbolic link)
Now I do:
cd ~/Desktop/subdir
Which leads me into the linked directory.
If I now issue the command:
cd ..
I will be moved back into the Desktop directory. This means the cd command is context sensitive - it remembers that I entered subdir via the symbolic link.
However, issuing the command
cp testfile ..
will copy testfile into Desktop/Public.
I prefer the behavior of cd over the (often unpredictable) behavior of cp. In any case, I wonder what is the reason for this difference in behavior? Just a legacy thing or is there a good reason?
shell symlink cp cd-command
shell symlink cp cd-command
edited Jul 23 '13 at 3:34
Braiam
24.7k20 gold badges82 silver badges147 bronze badges
24.7k20 gold badges82 silver badges147 bronze badges
asked Jul 22 '13 at 13:24
Konstantin SchubertKonstantin Schubert
1501 silver badge6 bronze badges
1501 silver badge6 bronze badges
Btw., behaviour and behavior are both correct spellings.
– Konstantin Schubert
Jul 23 '13 at 10:38
add a comment |
Btw., behaviour and behavior are both correct spellings.
– Konstantin Schubert
Jul 23 '13 at 10:38
Btw., behaviour and behavior are both correct spellings.
– Konstantin Schubert
Jul 23 '13 at 10:38
Btw., behaviour and behavior are both correct spellings.
– Konstantin Schubert
Jul 23 '13 at 10:38
add a comment |
3 Answers
3
active
oldest
votes
The reason that cd is aware that you have entered the directory via a symlink is because it is built-in to the shell. The cp command is an external binary and is only passed data via command line arguments and environment variables. Environment variables do not contain data on how you entered the current directory.
If you are using bash, you can make cd function the same as cp if you want things to be consistent. set -P will accomplish this. From the manpage:
-P If set, the shell does not follow symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the
logical chain of directories when performing commands which change the current directory.
4
Actually, the PWD environment variable does contain data on how you entered the current directory.cpjust doesn't use it like Bash does.
– cjm
Jul 22 '13 at 14:38
Wouldn't it be nice if it did? I understand that there are legacy issues, but I think it would be much more user friendly if cp did consider the fact that I entered via a symbolic link.
– Konstantin Schubert
Jul 22 '13 at 17:13
1
@Konstantin Only shells setPWD. So if a shell starts program1 which starts program2, then program2 has no idea whether$PWDis still up-to-date.cphas no way to know that you entered through a symbolic link, this tracking is internal to the shell.
– Gilles
Jul 22 '13 at 21:46
add a comment |
When cd works as described it can only be a trick of cd or your shell. .. is an entry to the parent directory. In your case the parent of subdir can only be Public and not Desktop. Thus cp does the right think and you will get the same behavior with redirects (like >).
The cd example only uses some "user-friendly" trick to behave like it does. See https://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links
If you really need the functionality you have to use something like
cp testfile "${PWD##*/}"
(copy to the parent directory of the current directory, according to shell tracking). In zsh, you can simplify this to cp testfile $PWD:h
add a comment |
It's rather the opposite: cp behaves like any other application, it interprets .. as the parent directory of the current directory. That's because the kernel interprets .. as the parent directory of the current directory.
When you run cd through a symbolic link, the path that you pass to cd does not make the parent directory of the destination directory apparent. When you run cd ~/Desktop/subdir, the destination is not /home/konstantin/Desktop/subdir — that's a symbolic link. The destination directory is /home/konstantin/Desktop/Public/subdir. (Or, to be pedantic: the destination directory is a subdirectory called subdir of a subdirectory called Public of … of a subdirectory called home of the root directory.) /home/konstantin/Desktop/subdir/.. is not /home/konstantin/Desktop: the property that the parent directory of /…stuff…/subdir is /…stuff… only holds in the absence of subdirectories.
Because it's often convenient to think of symbolic links to directories as if they were directories, shells perform symbolic link tracking. When you run cd, the shell remembers which path (possibly using symbolic links) you've used to reach the destination. And when you use .. in an argument to cd (or similar shell builtins such as pushd), the shell performs a textual interpretation of .. rather than interpreting it as the current directory: cd /some/stuff/../more is transformed to cd /some/more. That way, cd behaves as if the symbolic links were actually directories.
Textual interpretation of .. is known as logical directory tracking, and filesystem interpretation of .. is known as physical directory tracking.
If you want to use physical directory tracking (i.e. to turn off textual interpretation of ..), pass the -P option to cd. The -L option forces logical tracking on, in case it's been disabled. Logical tracking is off by default; you can turn it off with set -P in bash or with setopt chase_links in zsh.
The command pwd displays the current directory as tracked by the shell. Like cd, you can pass the option -L or -P to force logical or physical tracking.
All this is happening inside the shell. External applications such as cp have no way to know what tracking the shell is doing internally. So if you want to use logical directory tracking in an argument to a command, you need to convert that first to a path that doesn't depend on logical tracking.
The shell variable PWD keeps track of the current directory ($PWD contains the same string that pwd prints). If you want to strip off the last textual component of the tracked path to the current directory, instead of appending /.. which only works with logical tracking, you can use a textual method.
cp testfile "${PWD##*/}"
or in zsh:
cp testfile $PWD:h
If you want to type .. and not have to think about expressing the directory differently, run cd to the desired target directory, and then use the path to the destination in the argument of the command.
cp testfile "$(cd .. && pwd)"
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f83966%2fcp-somefile-copies-to-a-different-directory-after-cding-via-a-symbolic-link%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The reason that cd is aware that you have entered the directory via a symlink is because it is built-in to the shell. The cp command is an external binary and is only passed data via command line arguments and environment variables. Environment variables do not contain data on how you entered the current directory.
If you are using bash, you can make cd function the same as cp if you want things to be consistent. set -P will accomplish this. From the manpage:
-P If set, the shell does not follow symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the
logical chain of directories when performing commands which change the current directory.
4
Actually, the PWD environment variable does contain data on how you entered the current directory.cpjust doesn't use it like Bash does.
– cjm
Jul 22 '13 at 14:38
Wouldn't it be nice if it did? I understand that there are legacy issues, but I think it would be much more user friendly if cp did consider the fact that I entered via a symbolic link.
– Konstantin Schubert
Jul 22 '13 at 17:13
1
@Konstantin Only shells setPWD. So if a shell starts program1 which starts program2, then program2 has no idea whether$PWDis still up-to-date.cphas no way to know that you entered through a symbolic link, this tracking is internal to the shell.
– Gilles
Jul 22 '13 at 21:46
add a comment |
The reason that cd is aware that you have entered the directory via a symlink is because it is built-in to the shell. The cp command is an external binary and is only passed data via command line arguments and environment variables. Environment variables do not contain data on how you entered the current directory.
If you are using bash, you can make cd function the same as cp if you want things to be consistent. set -P will accomplish this. From the manpage:
-P If set, the shell does not follow symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the
logical chain of directories when performing commands which change the current directory.
4
Actually, the PWD environment variable does contain data on how you entered the current directory.cpjust doesn't use it like Bash does.
– cjm
Jul 22 '13 at 14:38
Wouldn't it be nice if it did? I understand that there are legacy issues, but I think it would be much more user friendly if cp did consider the fact that I entered via a symbolic link.
– Konstantin Schubert
Jul 22 '13 at 17:13
1
@Konstantin Only shells setPWD. So if a shell starts program1 which starts program2, then program2 has no idea whether$PWDis still up-to-date.cphas no way to know that you entered through a symbolic link, this tracking is internal to the shell.
– Gilles
Jul 22 '13 at 21:46
add a comment |
The reason that cd is aware that you have entered the directory via a symlink is because it is built-in to the shell. The cp command is an external binary and is only passed data via command line arguments and environment variables. Environment variables do not contain data on how you entered the current directory.
If you are using bash, you can make cd function the same as cp if you want things to be consistent. set -P will accomplish this. From the manpage:
-P If set, the shell does not follow symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the
logical chain of directories when performing commands which change the current directory.
The reason that cd is aware that you have entered the directory via a symlink is because it is built-in to the shell. The cp command is an external binary and is only passed data via command line arguments and environment variables. Environment variables do not contain data on how you entered the current directory.
If you are using bash, you can make cd function the same as cp if you want things to be consistent. set -P will accomplish this. From the manpage:
-P If set, the shell does not follow symbolic links when executing commands such as cd that change the current working directory. It uses the physical directory structure instead. By default, bash follows the
logical chain of directories when performing commands which change the current directory.
answered Jul 22 '13 at 13:50
jordanmjordanm
32.5k3 gold badges92 silver badges100 bronze badges
32.5k3 gold badges92 silver badges100 bronze badges
4
Actually, the PWD environment variable does contain data on how you entered the current directory.cpjust doesn't use it like Bash does.
– cjm
Jul 22 '13 at 14:38
Wouldn't it be nice if it did? I understand that there are legacy issues, but I think it would be much more user friendly if cp did consider the fact that I entered via a symbolic link.
– Konstantin Schubert
Jul 22 '13 at 17:13
1
@Konstantin Only shells setPWD. So if a shell starts program1 which starts program2, then program2 has no idea whether$PWDis still up-to-date.cphas no way to know that you entered through a symbolic link, this tracking is internal to the shell.
– Gilles
Jul 22 '13 at 21:46
add a comment |
4
Actually, the PWD environment variable does contain data on how you entered the current directory.cpjust doesn't use it like Bash does.
– cjm
Jul 22 '13 at 14:38
Wouldn't it be nice if it did? I understand that there are legacy issues, but I think it would be much more user friendly if cp did consider the fact that I entered via a symbolic link.
– Konstantin Schubert
Jul 22 '13 at 17:13
1
@Konstantin Only shells setPWD. So if a shell starts program1 which starts program2, then program2 has no idea whether$PWDis still up-to-date.cphas no way to know that you entered through a symbolic link, this tracking is internal to the shell.
– Gilles
Jul 22 '13 at 21:46
4
4
Actually, the PWD environment variable does contain data on how you entered the current directory.
cp just doesn't use it like Bash does.– cjm
Jul 22 '13 at 14:38
Actually, the PWD environment variable does contain data on how you entered the current directory.
cp just doesn't use it like Bash does.– cjm
Jul 22 '13 at 14:38
Wouldn't it be nice if it did? I understand that there are legacy issues, but I think it would be much more user friendly if cp did consider the fact that I entered via a symbolic link.
– Konstantin Schubert
Jul 22 '13 at 17:13
Wouldn't it be nice if it did? I understand that there are legacy issues, but I think it would be much more user friendly if cp did consider the fact that I entered via a symbolic link.
– Konstantin Schubert
Jul 22 '13 at 17:13
1
1
@Konstantin Only shells set
PWD. So if a shell starts program1 which starts program2, then program2 has no idea whether $PWD is still up-to-date. cp has no way to know that you entered through a symbolic link, this tracking is internal to the shell.– Gilles
Jul 22 '13 at 21:46
@Konstantin Only shells set
PWD. So if a shell starts program1 which starts program2, then program2 has no idea whether $PWD is still up-to-date. cp has no way to know that you entered through a symbolic link, this tracking is internal to the shell.– Gilles
Jul 22 '13 at 21:46
add a comment |
When cd works as described it can only be a trick of cd or your shell. .. is an entry to the parent directory. In your case the parent of subdir can only be Public and not Desktop. Thus cp does the right think and you will get the same behavior with redirects (like >).
The cd example only uses some "user-friendly" trick to behave like it does. See https://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links
If you really need the functionality you have to use something like
cp testfile "${PWD##*/}"
(copy to the parent directory of the current directory, according to shell tracking). In zsh, you can simplify this to cp testfile $PWD:h
add a comment |
When cd works as described it can only be a trick of cd or your shell. .. is an entry to the parent directory. In your case the parent of subdir can only be Public and not Desktop. Thus cp does the right think and you will get the same behavior with redirects (like >).
The cd example only uses some "user-friendly" trick to behave like it does. See https://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links
If you really need the functionality you have to use something like
cp testfile "${PWD##*/}"
(copy to the parent directory of the current directory, according to shell tracking). In zsh, you can simplify this to cp testfile $PWD:h
add a comment |
When cd works as described it can only be a trick of cd or your shell. .. is an entry to the parent directory. In your case the parent of subdir can only be Public and not Desktop. Thus cp does the right think and you will get the same behavior with redirects (like >).
The cd example only uses some "user-friendly" trick to behave like it does. See https://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links
If you really need the functionality you have to use something like
cp testfile "${PWD##*/}"
(copy to the parent directory of the current directory, according to shell tracking). In zsh, you can simplify this to cp testfile $PWD:h
When cd works as described it can only be a trick of cd or your shell. .. is an entry to the parent directory. In your case the parent of subdir can only be Public and not Desktop. Thus cp does the right think and you will get the same behavior with redirects (like >).
The cd example only uses some "user-friendly" trick to behave like it does. See https://stackoverflow.com/questions/10456784/behavior-of-cd-bash-on-symbolic-links
If you really need the functionality you have to use something like
cp testfile "${PWD##*/}"
(copy to the parent directory of the current directory, according to shell tracking). In zsh, you can simplify this to cp testfile $PWD:h
edited May 23 '17 at 12:39
Community♦
1
1
answered Jul 22 '13 at 14:06
dordor
1013 bronze badges
1013 bronze badges
add a comment |
add a comment |
It's rather the opposite: cp behaves like any other application, it interprets .. as the parent directory of the current directory. That's because the kernel interprets .. as the parent directory of the current directory.
When you run cd through a symbolic link, the path that you pass to cd does not make the parent directory of the destination directory apparent. When you run cd ~/Desktop/subdir, the destination is not /home/konstantin/Desktop/subdir — that's a symbolic link. The destination directory is /home/konstantin/Desktop/Public/subdir. (Or, to be pedantic: the destination directory is a subdirectory called subdir of a subdirectory called Public of … of a subdirectory called home of the root directory.) /home/konstantin/Desktop/subdir/.. is not /home/konstantin/Desktop: the property that the parent directory of /…stuff…/subdir is /…stuff… only holds in the absence of subdirectories.
Because it's often convenient to think of symbolic links to directories as if they were directories, shells perform symbolic link tracking. When you run cd, the shell remembers which path (possibly using symbolic links) you've used to reach the destination. And when you use .. in an argument to cd (or similar shell builtins such as pushd), the shell performs a textual interpretation of .. rather than interpreting it as the current directory: cd /some/stuff/../more is transformed to cd /some/more. That way, cd behaves as if the symbolic links were actually directories.
Textual interpretation of .. is known as logical directory tracking, and filesystem interpretation of .. is known as physical directory tracking.
If you want to use physical directory tracking (i.e. to turn off textual interpretation of ..), pass the -P option to cd. The -L option forces logical tracking on, in case it's been disabled. Logical tracking is off by default; you can turn it off with set -P in bash or with setopt chase_links in zsh.
The command pwd displays the current directory as tracked by the shell. Like cd, you can pass the option -L or -P to force logical or physical tracking.
All this is happening inside the shell. External applications such as cp have no way to know what tracking the shell is doing internally. So if you want to use logical directory tracking in an argument to a command, you need to convert that first to a path that doesn't depend on logical tracking.
The shell variable PWD keeps track of the current directory ($PWD contains the same string that pwd prints). If you want to strip off the last textual component of the tracked path to the current directory, instead of appending /.. which only works with logical tracking, you can use a textual method.
cp testfile "${PWD##*/}"
or in zsh:
cp testfile $PWD:h
If you want to type .. and not have to think about expressing the directory differently, run cd to the desired target directory, and then use the path to the destination in the argument of the command.
cp testfile "$(cd .. && pwd)"
add a comment |
It's rather the opposite: cp behaves like any other application, it interprets .. as the parent directory of the current directory. That's because the kernel interprets .. as the parent directory of the current directory.
When you run cd through a symbolic link, the path that you pass to cd does not make the parent directory of the destination directory apparent. When you run cd ~/Desktop/subdir, the destination is not /home/konstantin/Desktop/subdir — that's a symbolic link. The destination directory is /home/konstantin/Desktop/Public/subdir. (Or, to be pedantic: the destination directory is a subdirectory called subdir of a subdirectory called Public of … of a subdirectory called home of the root directory.) /home/konstantin/Desktop/subdir/.. is not /home/konstantin/Desktop: the property that the parent directory of /…stuff…/subdir is /…stuff… only holds in the absence of subdirectories.
Because it's often convenient to think of symbolic links to directories as if they were directories, shells perform symbolic link tracking. When you run cd, the shell remembers which path (possibly using symbolic links) you've used to reach the destination. And when you use .. in an argument to cd (or similar shell builtins such as pushd), the shell performs a textual interpretation of .. rather than interpreting it as the current directory: cd /some/stuff/../more is transformed to cd /some/more. That way, cd behaves as if the symbolic links were actually directories.
Textual interpretation of .. is known as logical directory tracking, and filesystem interpretation of .. is known as physical directory tracking.
If you want to use physical directory tracking (i.e. to turn off textual interpretation of ..), pass the -P option to cd. The -L option forces logical tracking on, in case it's been disabled. Logical tracking is off by default; you can turn it off with set -P in bash or with setopt chase_links in zsh.
The command pwd displays the current directory as tracked by the shell. Like cd, you can pass the option -L or -P to force logical or physical tracking.
All this is happening inside the shell. External applications such as cp have no way to know what tracking the shell is doing internally. So if you want to use logical directory tracking in an argument to a command, you need to convert that first to a path that doesn't depend on logical tracking.
The shell variable PWD keeps track of the current directory ($PWD contains the same string that pwd prints). If you want to strip off the last textual component of the tracked path to the current directory, instead of appending /.. which only works with logical tracking, you can use a textual method.
cp testfile "${PWD##*/}"
or in zsh:
cp testfile $PWD:h
If you want to type .. and not have to think about expressing the directory differently, run cd to the desired target directory, and then use the path to the destination in the argument of the command.
cp testfile "$(cd .. && pwd)"
add a comment |
It's rather the opposite: cp behaves like any other application, it interprets .. as the parent directory of the current directory. That's because the kernel interprets .. as the parent directory of the current directory.
When you run cd through a symbolic link, the path that you pass to cd does not make the parent directory of the destination directory apparent. When you run cd ~/Desktop/subdir, the destination is not /home/konstantin/Desktop/subdir — that's a symbolic link. The destination directory is /home/konstantin/Desktop/Public/subdir. (Or, to be pedantic: the destination directory is a subdirectory called subdir of a subdirectory called Public of … of a subdirectory called home of the root directory.) /home/konstantin/Desktop/subdir/.. is not /home/konstantin/Desktop: the property that the parent directory of /…stuff…/subdir is /…stuff… only holds in the absence of subdirectories.
Because it's often convenient to think of symbolic links to directories as if they were directories, shells perform symbolic link tracking. When you run cd, the shell remembers which path (possibly using symbolic links) you've used to reach the destination. And when you use .. in an argument to cd (or similar shell builtins such as pushd), the shell performs a textual interpretation of .. rather than interpreting it as the current directory: cd /some/stuff/../more is transformed to cd /some/more. That way, cd behaves as if the symbolic links were actually directories.
Textual interpretation of .. is known as logical directory tracking, and filesystem interpretation of .. is known as physical directory tracking.
If you want to use physical directory tracking (i.e. to turn off textual interpretation of ..), pass the -P option to cd. The -L option forces logical tracking on, in case it's been disabled. Logical tracking is off by default; you can turn it off with set -P in bash or with setopt chase_links in zsh.
The command pwd displays the current directory as tracked by the shell. Like cd, you can pass the option -L or -P to force logical or physical tracking.
All this is happening inside the shell. External applications such as cp have no way to know what tracking the shell is doing internally. So if you want to use logical directory tracking in an argument to a command, you need to convert that first to a path that doesn't depend on logical tracking.
The shell variable PWD keeps track of the current directory ($PWD contains the same string that pwd prints). If you want to strip off the last textual component of the tracked path to the current directory, instead of appending /.. which only works with logical tracking, you can use a textual method.
cp testfile "${PWD##*/}"
or in zsh:
cp testfile $PWD:h
If you want to type .. and not have to think about expressing the directory differently, run cd to the desired target directory, and then use the path to the destination in the argument of the command.
cp testfile "$(cd .. && pwd)"
It's rather the opposite: cp behaves like any other application, it interprets .. as the parent directory of the current directory. That's because the kernel interprets .. as the parent directory of the current directory.
When you run cd through a symbolic link, the path that you pass to cd does not make the parent directory of the destination directory apparent. When you run cd ~/Desktop/subdir, the destination is not /home/konstantin/Desktop/subdir — that's a symbolic link. The destination directory is /home/konstantin/Desktop/Public/subdir. (Or, to be pedantic: the destination directory is a subdirectory called subdir of a subdirectory called Public of … of a subdirectory called home of the root directory.) /home/konstantin/Desktop/subdir/.. is not /home/konstantin/Desktop: the property that the parent directory of /…stuff…/subdir is /…stuff… only holds in the absence of subdirectories.
Because it's often convenient to think of symbolic links to directories as if they were directories, shells perform symbolic link tracking. When you run cd, the shell remembers which path (possibly using symbolic links) you've used to reach the destination. And when you use .. in an argument to cd (or similar shell builtins such as pushd), the shell performs a textual interpretation of .. rather than interpreting it as the current directory: cd /some/stuff/../more is transformed to cd /some/more. That way, cd behaves as if the symbolic links were actually directories.
Textual interpretation of .. is known as logical directory tracking, and filesystem interpretation of .. is known as physical directory tracking.
If you want to use physical directory tracking (i.e. to turn off textual interpretation of ..), pass the -P option to cd. The -L option forces logical tracking on, in case it's been disabled. Logical tracking is off by default; you can turn it off with set -P in bash or with setopt chase_links in zsh.
The command pwd displays the current directory as tracked by the shell. Like cd, you can pass the option -L or -P to force logical or physical tracking.
All this is happening inside the shell. External applications such as cp have no way to know what tracking the shell is doing internally. So if you want to use logical directory tracking in an argument to a command, you need to convert that first to a path that doesn't depend on logical tracking.
The shell variable PWD keeps track of the current directory ($PWD contains the same string that pwd prints). If you want to strip off the last textual component of the tracked path to the current directory, instead of appending /.. which only works with logical tracking, you can use a textual method.
cp testfile "${PWD##*/}"
or in zsh:
cp testfile $PWD:h
If you want to type .. and not have to think about expressing the directory differently, run cd to the desired target directory, and then use the path to the destination in the argument of the command.
cp testfile "$(cd .. && pwd)"
answered Jul 23 '13 at 1:55
GillesGilles
572k139 gold badges1182 silver badges1693 bronze badges
572k139 gold badges1182 silver badges1693 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f83966%2fcp-somefile-copies-to-a-different-directory-after-cding-via-a-symbolic-link%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Btw., behaviour and behavior are both correct spellings.
– Konstantin Schubert
Jul 23 '13 at 10:38