每个进程都有一个当前目录。当一个进程启动时,它只是从其父进程继承当前目录;例如,它没有设置为包含您正在运行的程序的目录。
如需更详细的解释,请继续阅读。
当磁盘变得足够大以至于您不希望所有文件都放在同一个地方时,操作系统供应商想出了一种在其中构建文件的方法目录。因此,您可以在其中创建新集合和其他新集合(除了在某些早期实现中,目录不能包含其他目录!),而不是将所有内容保存在同一目录(或初学者现在被教导的“文件夹”)中。
从根本上讲,目录只是一种特殊类型的文件,其内容是其他文件的集合,其中还可以包括其他目录。
在原始操作系统上,故事就到此结束了。如果你想打印一个名为term_paper.txt
这是在目录中spring_semester
这又在目录中2021
这是在目录中studies
在目录中mine
,你不得不说
print mine/studies/2021/spring_semester/term_paper.txt
(除了该命令可能比print
,目录分隔符可能是一些疯狂的东西,比如方括号和冒号,或者其他东西;
lpr [mine:studies:2021:spring_semester]term_paper.txt
但这对于本次说明并不重要),如果您想复制该文件,则必须将整个 enchilada 拼出两次:
copy mine/studies/2021/spring_semester/term_paper.txt mine/studies/2021/spring_semester/term_paper.backup
然后出现了当前工作目录的概念。如果你可以说“从现在开始,除非我另有说明,我正在谈论的所有文件都将位于这个特定目录中”,该怎么办?就这样cd
命令诞生(除了在像 VMS 这样的旧系统上,它被称为更笨重的东西,比如SET DEFAULT
).
cd mine/studies/2021/spring_semester
print term_paper.txt
copy term_paper.txt term_paper.backup
这就是全部内容了。当你cd
(或者,在 Python 中,os.chdir()
),您更改当前的工作目录。它会一直保留到您注销(或以其他方式退出此过程),或者直到您cd
到不同的工作目录,或者切换到不同的进程或窗口,在其中运行单独的命令its自己的当前工作目录。就像您可以在不同目录中使用多个窗口打开文件浏览器(Explorer 或 Finder 或 Nautilus 或其他任何名称)一样,您可以打开多个终端,并且每个终端都运行一个具有自己独立的当前工作目录的 shell。
所以当你输入pwd
进入终端(或cwd
或者无论命令在您的命令语言中被调用),结果很大程度上取决于您之前在该窗口或进程中执行的操作,并且可能取决于您如何创建该窗口或进程。在许多类 Unix 系统上,当您创建带有关联 shell 进程的新终端窗口时,它最初是在您的主目录中打开的(/home/you
在许多 Unix 系统上,/Users/you
在 Mac 上,或多或少类似于C:\Users\you
在最近的 Windows 上)尽管您的终端可能可以配置为在其他地方打开(通常Desktop
or Documents
在一些表面上“现代”和“友好”的系统上的主目录中)。
许多初学者对于运行程序时发生的情况有一个模糊且不完整的心理模型。很多人都会不断cd
进入包含他们的脚本或程序的目录,当你告诉他们你不必这样做时,你会感到真正的害怕和困惑。如果frobozz
is in /home/you/bin
那么你不必
cd /home/you/bin
./frobozz
因为你可以直接运行它
/home/you/bin/frobozz
类似地如果ls
is in /bin
你绝对不会
cd /bin
./ls
只是为了获取目录列表。
此外,像ls
(或者在 Windows 上,dir
)示例应该很容易说服您,您运行的任何程序都会查找your文件的当前目录。不是保存程序或脚本的目录。因为如果是这样的话,ls
只能生成其所在目录的列表(/bin
) -- 目录列表程序、复制程序或文字处理程序没有什么特别之处;根据设计,它们都在当前工作目录中查找(尽管有些 GUI 程序会再次查看)start例如你的Documents
目录作为他们当前的工作目录,按照设计,至少如果你不告诉他们的话)。
许多初学者编写的脚本要求输入和输出文件位于特定用户主目录中的特定目录中,但这只是糟糕的设计;除非另有指示,否则编写良好的程序将简单地在当前工作目录中查找其输入文件,并将输出写入当前目录(或者如果当前目录由多个文件组成,则可能在当前目录中为其输出创建一个新目录)。
那么,Python 与任何其他程序没有什么不同。如果您当前的工作目录是/Users/you/Documents
当你跑步时python
那么该目录是什么os.getcwd()
在你的Python脚本或解释器中会产生(除非你单独os.chdir()
在运行时到不同的目录;但同样,这可能是不必要的,并且通常表明脚本是由初学者编写的)。如果你的 Python 脚本接受文件名参数,它可能应该简单地让操作系统open
无论用户传入什么,这意味着相对文件名是相对于调用用户的当前工作目录的。
python /home/you/bin/script.py file.txt
应该简单地open(sys.argv[1])
如果出现错误则失败file.txt
当前目录中不存在。我们再说一遍;它不看进去/home/you/bin
for file.txt
-- 当然,除非这也是您(调用者)的当前工作目录,在这种情况下您当然可以简单地编写
python script.py file.txt
与此相关的是,许多初学者不必要地尝试类似的事情
with open(os.path.join(os.getcwd(), "input.txt")) as data:
...
这不必要地调用os.getcwd()
。为什么是不必要的呢?如果您一直在关注,您已经知道答案:操作系统将查找相对文件名(如下所示,input.txt
)无论如何在当前工作目录中。所以你需要的是
with open("input.txt") as data:
...
最后一句话。在类 Unix 系统上,所有文件最终都位于根目录中/
其中包含许多其他目录(通常不允许普通用户在那里写入任何内容,并且有权执行此操作的系统管理员通常不想这样做)。通过跟踪从根目录到当前目录的路径,每个相对文件名都可以转换为绝对文件名。所以如果我们要访问的文件位于/home/you/Documents/file.txt
代表着home
位于根目录中,包含you
, 其中包含Documents
, 其中包含file.txt
。如果您当前的工作目录是/home
您可以通过相对路径引用同一个文件you/Documents/file.txt
;如果您当前的目录是/home/you
,它的相对路径是Documents/file.txt
(如果您当前的目录是/home/you/Music
你可以说../Documents/file.txt
但现在我们不再继续这个例子)。
Windows 的安排略有不同,有许多带有单字母标识符的驱动器,每个驱动器都有自己的根目录;所以 C: 驱动器的根目录是C:\
D: 驱动器的根目录是D:\
等等(目录分隔符是反斜杠而不是斜杠,尽管您几乎可以在任何地方使用斜杠,这通常是保持理智的好主意)。