Python 为什么可以';你看不到我的文件吗?
我有一个简单的bash脚本,它允许Python 为什么可以';你看不到我的文件吗?,python,linux,bash,shell,virtualenv,Python,Linux,Bash,Shell,Virtualenv,我有一个简单的bash脚本,它允许cron在virtualenv中执行一系列Python脚本。脚本不断引发无此类文件或目录错误 ~/nightly.sh工作正常: #!/bin/bash source virt_env/myproject/bin/activate cd virt_env/myproject/main python script1.py python script2.py 我希望将所有内容都保存在~/virt\u env/myproject/main/中,以简化部署。我想我可以
cron
在virtualenv
中执行一系列Python脚本。脚本不断引发无此类文件或目录错误
~/nightly.sh
工作正常:
#!/bin/bash
source virt_env/myproject/bin/activate
cd virt_env/myproject/main
python script1.py
python script2.py
我希望将所有内容都保存在~/virt\u env/myproject/main/
中,以简化部署。我想我可以打电话给bash virt_env/myproject/main/nightly.sh
,关于这个:
#!/bin/bash
MAINDIR=`dirname $0`
cd $MAINDIR
source ../bin/activate
python script1.py
python script2.py
但是我得到的没有这样的文件或目录
。如果我手动cd
到~/virt\u env/myproject/main/
,那么我可以毫无问题地运行main命令。显然,我遗漏了一些关于dirname
和cd
在这种情况下是如何工作的
我怎样才能把bash指向正确的地方
解决方案
正如公认答案中所建议的,最好避免从脚本中调用cd
,而是使用显式路径变量。以下是工作版本的virt_env/myproject/main/nightly.sh
:
#!/bin/bash
MAINDIR=`dirname $0`
echo "The main directory is" $MAINDIR
# Activate virtual environment
source $MAINDIR/../bin/activate
# Run Python scripts
python $MAINDIR/python1.py
python $MAINDIR/python2.py
因为Python脚本现在是从任意路径调用的,所以我需要更新Python脚本,使其在路径感知方面更加智能
此代码失败,因为忽略了路径信息:
# works when called with "python python1.py"
# fails when called with "python $MAINDIR/python1.py"
CONFIG_FILE = os.path.basename(__file__)[:-3] + ".config"
f = open(CONFIG_FILE,"r")
将其更新为使用可修复此问题:
# works regardless of how it is called
CONFIG_FILE = os.path.abspath(__file__)[:-3] + ".config"
f = open(CONFIG_FILE,"r")
也许最好是取消“cd”命令。调用完整路径规范中的所有内容。在您的示例中,将$MAINDIR/添加到可执行文件中
然后,bash脚本可以位于可访问可执行文件的任何目录中。您不会遇到cd出现故障时发生的问题
例如:
cd yourdir
rm -f yourglob # oops things got removed from where you started if yourdir did not exist.
两件事:
- 您确定知道
dirname
命令在做什么吗?它将删除顶级目录以及任何调用它的地方的前导斜杠。我会绝对确保dirname
的输出与您认为的完全一致
例如,/home/user/
将输出/home
- 您正在使用
~
,它在您的环境中引用$HOME
变量。您没有提到cron
的列表位置,但请确保它不是以其他用户的身份运行的。Root的~
和您的~
将是两个完全不同的目录
这就是我所能想到的。我希望这有帮助 添加echo$MAINDIR
MAINDIR=`dirname $0`
cd $MAINDIR
您可以看到MAINDIR的内容是否正确
您还可以使用-x
运行sh,或者将set-x
添加到脚本的开头,以查看发生了什么情况。crontab条目是什么?我还没有将crontab加入到混合中,我只是像crontab一样从主目录启动bash脚本。echo“MAINDIR是$MAINDIR”
yieldsMAINDIR是virt\u env/myproject/main
。感谢您的回答。(编辑时间已满)是的,dirname
删除最后一个参数,因为我正在调用文件。因此,/path/to/file.txt
变成了/path/to
。使用此方法构建绝对路径似乎效果更好。714910*bash virt_env/myproject/main/nightly.sh的Chrontab似乎可以很好地处理新文件。