msg288467 - (view) |
Author: Fabien Dubosson (StreakyCobra) |
Date: 2017-02-23 18:40 |
When using bash, the `cd` function does not follow symlinks by default, but `cd -P` does. The `os.chdir` function behaves like `cd -P` preventing to be able to change directory to a symlink folder.
Initial setup (make a `/tmp/to/dst` symlink pointing to `/tmp/from/src`):
cd /tmp
mkdir from from/src to
ln -s ../from/src to/dst
Here is an example, when using python's `os.chdir` function:
[fabien@asus ~]$ python
>>> import os
>>> os.chdir('/tmp/to/dst')
>>> os.system('/usr/bin/pwd')
/tmp/from/src
0
>>> os.system('/usr/bin/pwd -P')
/tmp/from/src
0
>>> os.system('/usr/bin/pwd -L')
/tmp/from/src
0
>>> os.getcwd()
'/tmp/from/src'
>>>
And here is an example when the folder is first changed with bash:
[fabien@asus ~]$ cd /tmp/to/dst/
[fabien@asus dst]$ python
>>> import os
>>> os.system('/usr/bin/pwd')
/tmp/from/src
0
>>> os.system('/usr/bin/pwd -P')
/tmp/from/src
0
>>> os.system('/usr/bin/pwd -L')
/tmp/to/dst
0
>>> os.getcwd()
'/tmp/from/src'
>>>
|
msg288468 - (view) |
Author: Fabien Dubosson (StreakyCobra) |
Date: 2017-02-23 18:49 |
The previous example (sorry, first time using this platform, I'm a little bit messy here), shows that `os.chdir` resolves symlinks by default, as opposed to what `cd` does in bash. This means it is not possible to change the directory to a symlink folder.
A solution would be a keyword argument in `os.chdir` and `os.getcwd` that would mimic the `-P` and `-L` arguments of `cd` and `pwd`, like:
os.chdir(logical=False) # or follow_symlinks=True maybe
os.getcwd(logical=False)
I don't know what should be the default values for these args, but at least having an option to change the behavior would be nice.
|
msg288469 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2017-02-23 19:20 |
The function is chdir, not cd. The 'cd' man page says that 'cd -P' should "perform actions equivalent to the chdir() function".
So, you are asking for a different function, which should *not* be named 'os.chdir'. You'll have to make a case for it being useful enough to add.
The same applies to getcwd, which is also a wrapper for the posix function, not an emulation of the shell's pwd.
|
msg288474 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) * |
Date: 2017-02-23 19:52 |
'cd' is not an external command and has no manpage. It is a shell builtin command.
Most os functions are thin wrappers around system calls. There is no system call that works as 'cd' without '-P'.
If you implement a shell in Python, you perhaps need an implementation of the 'cd' command. But I have doubts that this is needed in the stdlib.
|
msg288475 - (view) |
Author: Fabien Dubosson (StreakyCobra) |
Date: 2017-02-23 19:59 |
Thanks for the additional information!
> The 'cd' man page says that 'cd -P' should "perform actions equivalent to the chdir() function".
Just wondering, do you know what is the function called by `cd`/`cd -L` then? It doesn't seems to be a bash internal tweak because `/usr/bin/pwd -L` is able to get the symlink path, and this binary is not part of bash.
> You'll have to make a case for it being useful enough to add.
The use case is for shells written in Python, like for instance `xonsh` [1,2]. Being powered by Python, the only way to change directory is by using `os.chdir()`. It is then not possible to mimic the bash `cd` function without using workarounds, like for instance storing the symlink path in a variable, and even this doesn't allow to use `/usr/bin/pwd -L` in scripts because it would always returns the physical location.
Having such described functions (yet to be named) would permit python shells to offer users differentiated `cd` and `cd -P` commands, as well as having `pwd -L` in scripts behaving the same than in traditional shells.
[1] http://xon.sh/
[2] https://github.com/xonsh/xonsh
|
msg288476 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2017-02-23 20:01 |
Since yours is the itch, I'm afraid you are going to have to be the one to figure out how this could be implemented :)
|
msg288478 - (view) |
Author: Fabien Dubosson (StreakyCobra) |
Date: 2017-02-23 20:05 |
> Most os functions are thin wrappers around system calls. There is no system call that works as 'cd' without '-P'.
I would like to believe in this, but then if `cd` is some bash internal, how does `/usr/bin/pwd -L` find it back?
> Since yours is the itch, I'm afraid you are going to have to be the one to figure out how this could be implemented :)
Once I'll have figured out how all this is working, maybe. Not sure it would me in my competencies though.
|
msg288480 - (view) |
Author: Serhiy Storchaka (serhiy.storchaka) * |
Date: 2017-02-23 20:07 |
> Just wondering, do you know what is the function called by `cd`/`cd -L` then? It doesn't seems to be a bash internal tweak because `/usr/bin/pwd -L` is able to get the symlink path, and this binary is not part of bash.
See shells sources. According to the manpage `pwd -L` just uses PWD from environment.
|
msg288481 - (view) |
Author: R. David Murray (r.david.murray) * |
Date: 2017-02-23 20:13 |
Ah, that should all be implementable from your python shell, then, no need for support in the os module.
For reference, when I said 'cd man page', this is what I was referring to:
http://www.unix.com/man-page/posix/1posix/cd/
I'm going to close this issue. If you find you do need access to some system interface the os module doesn't currently provide, you can open a specific issue for that.
|
msg288483 - (view) |
Author: Fabien Dubosson (StreakyCobra) |
Date: 2017-02-23 20:20 |
> I'm going to close this issue.
I was doing to do so, here was my message:
--------------------------------------------
> See shells sources. According to the manpage `pwd -L` just uses PWD from environment.
I looked directly at `pwd` sources, and indeed it is using $PWD [1].
[1] http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/pwd.c?id=509152bdd47a278dc00ddaf3200ac65044b836b1#n305
So it looks like `cd -L` is just some bash internal dealing with $PWD. Probably not something useful enough to be in the standard library, closing it then.
Sorry for the incovenience
|
|
Date |
User |
Action |
Args |
2022-04-11 14:58:43 | admin | set | github: 73821 |
2017-02-23 20:31:00 | serhiy.storchaka | set | status: open -> closed |
2017-02-23 20:20:29 | StreakyCobra | set | messages:
+ msg288483 |
2017-02-23 20:13:27 | r.david.murray | set | resolution: rejected messages:
+ msg288481 stage: resolved |
2017-02-23 20:07:16 | serhiy.storchaka | set | messages:
+ msg288480 |
2017-02-23 20:05:48 | StreakyCobra | set | messages:
+ msg288478 |
2017-02-23 20:01:24 | r.david.murray | set | messages:
+ msg288476 |
2017-02-23 19:59:18 | StreakyCobra | set | messages:
+ msg288475 |
2017-02-23 19:52:06 | serhiy.storchaka | set | nosy:
+ serhiy.storchaka messages:
+ msg288474
|
2017-02-23 19:21:20 | r.david.murray | set | type: behavior -> enhancement |
2017-02-23 19:20:45 | r.david.murray | set | versions:
- Python 2.7, Python 3.3, Python 3.4, Python 3.5, Python 3.6 nosy:
+ r.david.murray
messages:
+ msg288469
components:
+ Library (Lib), - Interpreter Core |
2017-02-23 18:49:34 | StreakyCobra | set | messages:
+ msg288468 |
2017-02-23 18:40:29 | StreakyCobra | set | messages:
+ msg288467 |
2017-02-23 18:31:00 | StreakyCobra | create | |