1

我有一个简单的 bash 脚本,它允许cronvirtualenv. 该脚本不断引发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")
4

3 回答 3

2

Perhaps it would simply be better to eliminate the 'cd' command. Invoke everything from a full path specification. In your example add $MAINDIR/ to the executables.

Your bash script can then be in any directory where the executables are reachable. You are not exposed to the problems of what happens when cd fails.

Example:

cd yourdir
rm -f yourglob   # oops things got removed from where you started if yourdir did not exist.
于 2013-10-08T23:15:19.283 回答
0

两件事情:

  • 你确定你知道这个dirname命令在做什么吗?它将删除顶级目录以及您调用它的任何前导斜杠。我会绝对确保 的输出dirname正是您认为的那样。

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

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

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

于 2013-10-09T02:57:57.077 回答
0

echo $MAINDIR之后添加

MAINDIR=`dirname $0`
cd $MAINDIR

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

您也可以运行 sh-x或添加set -x到脚本的开头以查看会发生什么。

于 2013-10-09T08:30:43.933 回答