我正在尝试使用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
这样做时,一切似乎都很糟糕。
答案 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 ...