python:将脚本工作目录更改为脚本自己的目录

发布于 2024-08-04 11:17:30 字数 376 浏览 4 评论 0原文

我每分钟从 crontab 运行一个 python shell:

* * * * * /home/udi/foo/bar.py

/home/udi/foo 有一些必要的子目录,例如 /home/udi/foo/log/home /udi/foo/config/home/udi/foo/bar.py 引用。

问题是 crontab 从不同的工作目录运行脚本,因此尝试打开 ./log/bar.log 失败。

有没有一种好方法告诉脚本将工作目录更改为脚本自己的目录?我想要一个适用于任何脚本位置的解决方案,而不是明确告诉脚本它在哪里。

I run a python shell from crontab every minute:

* * * * * /home/udi/foo/bar.py

/home/udi/foo has some necessary subdirectories, like /home/udi/foo/log and /home/udi/foo/config, which /home/udi/foo/bar.py refers to.

The problem is that crontab runs the script from a different working directory, so trying to open ./log/bar.log fails.

Is there a nice way to tell the script to change the working directory to the script's own directory? I would fancy a solution that would work for any script location, rather than explicitly telling the script where it is.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

思念满溢 2024-08-11 11:17:30

这会将您当前的工作目录更改为,以便打开相对路径可以工作:

import os
os.chdir("/home/udi/foo")

但是,您询问如何更改为 Python 脚本所在的任何目录,即使您不知道在编写脚本时该目录是什么脚本。为此,您可以使用 os.path 函数:

import os

abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

该函数获取脚本的文件名,将其转换为绝对路径,然后提取该路径的目录,然后更改为该目录。

This will change your current working directory to so that opening relative paths will work:

import os
os.chdir("/home/udi/foo")

However, you asked how to change into whatever directory your Python script is located, even if you don't know what directory that will be when you're writing your script. To do this, you can use the os.path functions:

import os

abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

This takes the filename of your script, converts it to an absolute path, then extracts the directory of that path, then changes into that directory.

浅浅淡淡 2024-08-11 11:17:30

您可以使用 sys.path[0] 获得较短的版本。

os.chdir(sys.path[0])

来自 http://docs.python.org/library/sys.html#sys。路径

在程序启动时初始化,该列表的第一项,
path[0],是包含用于执行的脚本的目录
调用Python解释器

You can get a shorter version by using sys.path[0].

os.chdir(sys.path[0])

From http://docs.python.org/library/sys.html#sys.path

As initialized upon program startup, the first item of this list,
path[0], is the directory containing the script that was used to
invoke the Python interpreter

甜妞爱困 2024-08-11 11:17:30

不要这样做。

您的脚本和数据不应混杂到一个大目录中。将您的代码放在与数据分开的某个已知位置(site-packages/var/opt/udi 或其他位置)。对代码使用良好的版本控制,以确保当前版本和以前的版本相互分离,以便您可以回退到以前的版本并测试未来的版本。

底线:不要混合代码和数据。

数据是宝贵的。代码来来去去。

提供工作目录作为命令行参数值。您可以提供默认值作为环境变量。不要推断它(或猜测它),

将其设为必需的参数值并执行此操作。

import sys
import os
working= os.environ.get("WORKING_DIRECTORY","/some/default")
if len(sys.argv) > 1: working = sys.argv[1]
os.chdir( working )

不要根据软件的位置“假定”目录。从长远来看,效果不会很好。

Don't do this.

Your scripts and your data should not be mashed into one big directory. Put your code in some known location (site-packages or /var/opt/udi or something) separate from your data. Use good version control on your code to be sure that you have current and previous versions separated from each other so you can fall back to previous versions and test future versions.

Bottom line: Do not mingle code and data.

Data is precious. Code comes and goes.

Provide the working directory as a command-line argument value. You can provide a default as an environment variable. Don't deduce it (or guess at it)

Make it a required argument value and do this.

import sys
import os
working= os.environ.get("WORKING_DIRECTORY","/some/default")
if len(sys.argv) > 1: working = sys.argv[1]
os.chdir( working )

Do not "assume" a directory based on the location of your software. It will not work out well in the long run.

寄与心 2024-08-11 11:17:30

将 crontab 命令更改为

* * * * * (cd /home/udi/foo/ || exit 1; ./bar.py)

(...) 启动一个子 shell,您的 crond 将其作为单个命令执行。 <代码>|| exit 1 会导致您的 cronjob 在目录不可用时失败。

尽管从长远来看,对于您的特定脚本而言,其他解决方案可能更优雅,但在您无法修改要执行的程序或命令的情况下,我的示例仍然有用。

Change your crontab command to

* * * * * (cd /home/udi/foo/ || exit 1; ./bar.py)

The (...) starts a sub-shell that your crond executes as a single command. The || exit 1 causes your cronjob to fail in case that the directory is unavailable.

Though the other solutions may be more elegant in the long run for your specific scripts, my example could still be useful in cases where you can't modify the program or command that you want to execute.

沦落红尘 2024-08-11 11:17:30

以防万一,您也可以使用 pathlib

import os
from pathlib import Path

file = Path(__file__)
parent = file.parent
os.chdir(parent)
# print(file, parent, os.getcwd())

或者在单行中:

os.chdir(Path(__file__).parent)

Just in case, you could also use pathlib

import os
from pathlib import Path

file = Path(__file__)
parent = file.parent
os.chdir(parent)
# print(file, parent, os.getcwd())

Or in single line:

os.chdir(Path(__file__).parent)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文