1

I was having a doubt.When I tried os.system(r'cd F:\') I was still in the directory where I started the interpreter.But `os.chdir()' worked fine.I'll show my code below:

>>> import os
>>> os.system('F:')
0

By running the os.system('dir') I found that I was still in the directory C:\python34.

Then I tried this:

>>> os.chdir('F:')

By running os.system('dir') I found that it worked fine.

Why is os.system('F:') not working? I would be pleased to get a help.

  • Could any of you guys please post it as an answer instead of a comment.It would be really helpful. –  Mar 22 '15 at 12:13

1 Answers1

1

os.system('F:') spawns a child shell process (i.e. the %ComSpec% shell, which is usually cmd.exe) and changes its working directory. It does not (and cannot) change the working directory of the parent process.

Note that the working directory is not stored per thread, i.e. it's not stored in the thread environment block (TEB) but process-wide in the process environment block (PEB). Generally avoid modifying the working directory in a multithreaded application. Instead use relative or fully-qualified paths.


Bonus Trivia: DOS Emulation

In addition to the process current working directory, Windows (the C runtime, actually) tracks the working directory on every DOS drive (e.g. C:) in hidden environment variables such as =C:. The initial '=' character keeps these variables from being displayed by the shell's set command, and it also filters them out of the C runtime environ that Python uses for os.environ. A bug in the command prompt will show these hidden variables if you pass an empty string to the set command, e.g. set "". Or in Python use ctypes to call GetEnvironmentVariable:

>>> from ctypes import *                            
>>> kernel32 = WinDLL('kernel32')
>>> kernel32.GetEnvironmentVariableW('=C:', None, 0)
8
>>> path = create_unicode_buffer(8)
>>> kernel32.GetEnvironmentVariableW('=C:', path, 8)
7
>>> path.value
'C:\\Temp'

Windows uses these hidden variables, if they exist, to resolve drive-relative paths. That said, the C runtime _chdir function is actually what creates/modifies them. A Windows program that only calls SetCurrentDirectory instead of POSIX chdir won't remember the per-drive working directory. Python's home-grown implementation of chdir on Windows has to implement this magic. See win32_chdir (3.4.3 source, Modules/posixmodule.c, line 1398).

Eryk Sun
  • 33,190
  • 5
  • 92
  • 111