0

我正在尝试使用 Unixat命令创建计划任务。我想运行一个 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

4 回答 4

0

我最近一直在研究服务器和客户端之间的任务调度。我只是抽象出我的调度代码并将其放在 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
于 2012-12-23T01:59:59.087 回答
0

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

at now + 1 minute < python mypythonscript.py

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

于 2012-12-23T00:58:31.743 回答
0

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

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

于 2012-12-23T01:09:47.193 回答
0

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

于 2012-12-25T20:36:53.977 回答