2012-12-23 28 views
0

我试图使用Unix at命令创建一个计划任务。我想运行一个python脚本,但很快意识到at被配置为使用运行我给它的任何文件sh。为了规避这种情况,我创建了一个包含命令python mypythonscript.py的文件,并将其传递给at使用python脚本调度unix`at`:权限被拒绝

我已经设置蟒文件被大家(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时,一切似乎都会变成垃圾。

+0

检查所有封闭目录的权限。必须有r + x。 – jman

+0

嗯,我正在使用分布式文件系统,所以我没有权利将所有的封闭文件夹更改为r + x。只是我拥有的那些。 (这也意味着我没有sudo访问权。) – Chiubaka

+0

尝试脚本的完整路径,因为'at'(它启动的子shell)可能使用不同的工作目录。 –

回答

0

编辑:at命令尝试运行一切作为shell命令的列表。所以,你应该开始你的脚本是这样的:

at now + 1 minute < python mypythonscript.py 

在这种情况下,#!线在脚本的开始是没有必要的。

+0

试过了。每当我运行'at'命令时,我都会明确告诫,命令将使用'/ bin/sh'来执行。当我尝试加载python文件时,即使使用'#!/ usr/bin/env python',我最终会得到一堆错误,因为我的python import语句被解释为一些X服务器命令。我后来还给出了'sh:line xx:命令格式错误' – Chiubaka

+0

你是如何调用at的? –

+0

'现在+ 1分钟 Chiubaka

0

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

at试图将所有内容都作为sh脚本运行。

+0

不知道我看到你所建议的和我已经做了什么之间的区别? – Chiubaka

+0

我的回答是在你编辑你的问题之前。 – OneOfOne

0

我一直在研究服务器和客户端之间的任务调度。我只是抽出我的日程安排代码和put it up on Github。这意味着要在多台机器上安排几次模拟,这些机器在其文件系统中都有模拟。这个想法是因为每台机器都有一个不同的处理器,它会计算每个模拟,将结果返回到服务器并请求服务器进行下一次模拟。服务器通过在客户端上安排任务来响应以运行下一个运行的下一个运行模拟

希望这会对您有所帮助。

注意:由于我只在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)[email protected]%(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 "[email protected]" 

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 [email protected]$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 
0

你能尝试:echo 'python mypythonscript.py' | at ...