为什么不能看到我的文件?

时间:2013-10-08 23:00:01

标签: python linux bash shell virtualenv

我有一个简单的bash脚本,允许cronvirtualenv中执行一系列Python脚本。该脚本不断引发No such file or directory错误。

~/nightly.sh效果很好:

#!/bin/bash
source virt_env/myproject/bin/activate
cd virt_env/myproject/main
python script1.py
python script2.py

我希望将所有内容保留在~/virt_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

但我得到了No such file or directory。如果我手动cd~/virt_env/myproject/main/,那么我可以运行主命令没问题。很明显,我遗漏了dirnamecd在这种情况下的工作方式。

如何将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脚本以便更加智能地了解路径感知。

此代码失败,因为os.path.basename省略了路径信息:

# 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")

将其更新为使用os.path.abspath可解决问题:

# works regardless of how it is called
CONFIG_FILE = os.path.abspath(__file__)[:-3] + ".config"
f = open(CONFIG_FILE,"r")

3 个答案:

答案 0 :(得分:2)

也许删除'cd'命令会更好。从完整路径规范中调用所有内容。在您的示例中,将$ MAINDIR /添加到可执行文件中。

然后,您的bash脚本可以位于可访问可执行文件的任何目录中。你没有遇到cd失败时会发生什么问题。

示例:

cd yourdir
rm -f yourglob   # oops things got removed from where you started if yourdir did not exist.

答案 1 :(得分:0)

两件事:

  • 您确定知道dirname命令在做什么吗?它将删除顶级目录以及任何您调用它的前导斜杠。我绝对肯定dirname的输出正是你所想的。

    例如,/home/user/将输出/home

  • 您使用的是~,它引用了您环境中的$HOME变量。您没有提到列出cron的位置,但请确保它不是以其他用户身份运行。 Root的~和您的~将是两个完全不同的目录。

这就是我所能想到的。我希望有所帮助!

答案 2 :(得分:0)

之后添加echo $MAINDIR
MAINDIR=`dirname $0`
cd $MAINDIR

所以你可以看到,如果MAINDIR的内容是正确的。

此外,您可以使用-x运行sh或将set -x添加到脚本的开头,以查看会发生什么。