Unix`at`调度与python脚本:权限被拒绝

时间:2012-12-23 00:37:16

标签: python linux shell unix

我正在尝试使用Unix at命令创建计划任务。我想运行一个python脚本,但很快意识到at被配置为使用sh运行我提供的任何文件。为了避免这种情况,我创建了一个包含命令python mypythonscript.py的文件,并将其传递给at

我已经将python文件的权限设置为可由所有人(chmod a+x)执行,但是当at作业运行时,我被告知python: can't open file 'mypythonscript.py': [Errno 13] Permission denied

如果我运行source myshwrapperscript.sh,shell脚本会调用python脚本。是否有一些明显的原因导致我遇到at的权限问题?

编辑:我对python脚本感到沮丧,所以我继续编写了我想要运行的sh脚本版本。我现在发现sh脚本返回给我说rm: cannot remove <filename>: Permission denied(这是我创建的用于存储中间数据的临时文件)。无论如何,我可以使用我自己的凭据授权这些操作,尽管没有sudo访问权限?当我自己运行它时,所有这些都能很好地工作,但是当我at这样做时,一切似乎都很糟糕。

4 个答案:

答案 0 :(得分:0)

编辑: at命令尝试将所有内容作为shell命令列表运行。所以你应该像这样开始你的脚本:

at now + 1 minute < python mypythonscript.py

在这种情况下,脚本开头的#!行不是必需的。

答案 1 :(得分:0)

使用python而不是实际的脚本名称启动脚本,例如:python path/to/script.py

尝试将所有内容作为sh脚本运行。

答案 2 :(得分:0)

我最近一直致力于服务器和客户端之间的任务调度。我只是抽象出我的调度代码和put it up on Github。它的目的是在多个机器上安排几个模拟,这些机器在其文件系统中具有所有模拟。这个想法是,由于每台机器都有不同的处理器,它会计算每次模拟,将结果scp回服务器并请求服务器进行下一次模拟。服务器通过在客户端上安排任务来运行下一个非运行模拟来响应

希望这会对你有所帮助。

注意:由于我仅在5分钟前抽象并上传文件,因此我没有机会测试抽象。但是,如果您遇到任何错误,请告诉我,我会尽快调试。

Github现在似乎已经失败了。以下是您需要的文件:

在服务器上

serverside

#!/bin/bash

projectDir=~/

minute=`atq | sort -t" " -k1 -nr | head -n1 | cut -d' ' -f4 | cut -d":" -f1,2`
curr=`date | cut -d' ' -f4 | cut -d':' -f1,2`

time=`python -c "import sys; hour,minute=map(int,max(sys.argv[1:]).split(':')); minute += 2; hour, minute = [(hour,minute), ((hour+1)%24,minute%60)][minute>=60]; print '%d:%02d'%(hour, minute)" "$minute" "$curr"`

cat <<EOF | at "$time"
python $projectDir/serverside.py $1

EOF

serverside.py

import sys
import time
import smtplib
import subprocess
import os
import itertools

IP = sys.argv[1].strip()
PROJECT_DIR = "" # relative path (relative to the home directory) to the root directory of the project, which contains all subdirs containing simulation files

USERS = { # keys are IPs of the clients, values are user names on those clients
        }

HOMES = { # keys are the IPs of clients, values are the absolute paths to the home directories on these clients for the usernames on these clients  identified in USERS
        }
HOME = None # absolute path to the home directory on the server

SMTP_SERVER = ""
SMTP_PORT = None
FROM_ADDR = None # the email address from which notification emails will be sent
TO_ADDR = None # the email address to which notification emails will be sent

def get_next_simulation():
    """ This function returns a list.
        The list contains N>0 elements.
        Each of the first N-1 elements are names of directories (not paths), which when joined together form a relative path (relative from PROJECT_DIR).
        The Nth element is the name of the file - the simulation to be run.
        Before the end user implements this function, it is assumed that N=3.
        Once this function has been implemented, if N!=3, change the code in the lines annotated with "Change code for N in this line"
             Also look for this annotation in clientside.py and clientsideexec """

    pass

done = False
DIR1, DIR2, FILENAME = get_next_simulation() # Change code for N in this line

while not done:
    try:
        subprocess.check_call("""ssh %(user)s@%(host)s 'sh %(home)s/%(project)/clientside %(dir1)s %(dir2)s %(filename)s %(host)s' """ %{'user':USER, 'host':IP, 'home':HOME[IP], 'project':PRJECT_DIR, 'dir1':DIR1, 'dir2':DIR2, 'filename':FILENAME}, shell=True) # Change code for N in this line
        done = True

        os.remove("%(home)s/%(project)/%(dir1)s/%(dir2)s/%(filename)s" %{'home':HOME, 'project':PROJECT_DIR, 'dir1':DIR1, 'dir2':DIR2, 'filename':FILENAME}) # Change code for N in this line

        sm = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        sm.sendmail(FROM_ADDR, TO_ADDR, "running %(project)s/%(dir1)s/%(dir2)s/%(filename)s on %(host)s" %{'project':PROJECT_DIR, 'dir1':DIR1, 'dir2':DIR2, 'filename':FILENAME, 'host':IP}) # Change code for N in this line
    except:
        pass

在客户端

clientside

#!/bin/bash

projectpath=~/
python $projectpath/clientside.py "$@"

clientside.py

import subprocess
import sys
import datetime
import os

DIR1, DIR2, FILENAME, IP = sys.argv[1:]
try:
    subprocess.check_call("sh ~/cisdagp/clientsideexec %(dir1)s %(dir2)s %(filename)s %(ip)s" %{'dir1':, 'dir2':, 'filename':, ip':IP}, shell=True, executable='/bin/bash') # Change code for N in this line

except:
    pass

clientsideexec

#!/bin/bash

projectpath=~/
user=''
serverIP=''

SMTP_SERVER=''
SMTP_PORT=''
FROM_ADDR=''
TO_ADDR=''
MESSAGE=''

cat <<EOF | at now + 2 minutes
cd $projectpath/$1/$2  # Change code for N in this line
sh $3

# copy the logfile back to the server
scp logfile$3 $user@$serverIP:$projectpath/$1/$2/
cd $projectpath
python -c "import smtplib; sm = smtplib.SMTP('$SMTP_SERVER', $SMTP_PORT); sm.sendmail('$FROM_ADDR', '$TO_ADDR', '$MESSAGE')"
python clientsiderequest.py
EOF

答案 3 :(得分:0)

您可以尝试:echo 'python mypythonscript.py' | at ...