推送操作系统

2024-10-05 22:43:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用crontab为我的minecraft服务器运行维护脚本。除非crontab尝试使用restart脚本,否则大多数情况下它都可以正常工作。如果手动运行重新启动脚本,则不会出现任何问题。因为我相信这与路径名有关,所以我试图确保它总是执行minecraft目录中的任何minecraft命令。所以我将命令封装在pushd/popd中:

os.system("pushd /directory/path/here")
os.system("command to sent to minecraft")
os.system("popd")

下面是一个互动环节,让minecraft摆脱困境。一个简单的“ls”测试。如您所见,它根本不从pushd目录运行os.system命令,而是从/etc/目录运行python来说明我的观点。谢谢!

>>> def test():
...     import os
...     os.system("pushd /home/[path_goes_here]/minecraft")
...     os.system("ls")
...     os.system("popd")
... 
>>> test()
~/minecraft /etc
DIR_COLORS    cron.weekly  gcrypt         inputrc    localtime   mime.types         ntp       ppp         rc3.d       sasldb2         smrsh      vsftpd.ftpusers
DIR_COLORS.xterm  crontab      gpm-root.conf      iproute2   login.defs  mke2fs.conf            ntp.conf      printcap        rc4.d       screenrc        snmp       vsftpd.tpsave
X11       csh.cshrc    group          issue      logrotate.conf  modprobe.d         odbc.ini      profile         rc5.d       scsi_id.config  squirrelmail   vz
adjtime       csh.login    group-         issue.net  logrotate.d     motd               odbcinst.ini  profile.d       rc6.d       securetty       ssh        warnquota.conf
aliases       cyrus.conf   host.conf      java       lvm         mtab               openldap      protocols       redhat-release  security        stunnel        webalizer.conf
alsa          dbus-1       hosts          jvm        lynx-site.cfg   multipath.conf         opt       quotagrpadmins  resolv.conf     selinux         sudoers        wgetrc
alternatives      default      hosts.allow    jvm-commmon    lynx.cfg    my.cnf             pam.d         quotatab        rndc.key        sensors.conf    sysconfig      xinetd.conf
bashrc        depmod.d     hosts.deny     jwhois.conf    mail        named.caching-nameserver.conf  passwd        rc          rpc         services        sysctl.conf    xinetd.d
blkid         dev.d        httpd          krb5.conf  mail.rc     named.conf         passwd-       rc.d        rpm         sestatus.conf   termcap        yum
cron.d        environment  imapd.conf     ld.so.cache    mailcap     named.rfc1912.zones        pear.conf     rc.local        rsyslog.conf    setuptool.d     udev       yum.conf
cron.daily    exports      imapd.conf.tpsave  ld.so.conf     mailman     netplug            php.d         rc.sysinit      rwtab       shadow          updatedb.conf  yum.repos.d
cron.deny     filesystems  init.d         ld.so.conf.d   makedev.d   netplug.d          php.ini       rc0.d       rwtab.d         shadow-         vimrc
cron.hourly   fonts        initlog.conf   libaudit.conf  man.config  nscd.conf          pki       rc1.d       samba       shells          virc
cron.monthly      fstab        inittab        libuser.conf   maven       nsswitch.conf          postfix       rc2.d       sasl2       skel        vsftpd
sh: line 0: popd: directory stack empty

=== (带有Python2.4的CentOS服务器)


Tags: 命令目录脚本osconfsysteminicron
3条回答

在Python2.5及更高版本中,我认为更好的方法是使用上下文管理器,如下所示:

import contextlib
import os


@contextlib.contextmanager
def pushd(new_dir):
    previous_dir = os.getcwd()
    os.chdir(new_dir)
    yield
    os.chdir(previous_dir)

然后您可以按如下方式使用它:

with pushd('somewhere'):
    print os.getcwd() # "somewhere"

print os.getcwd() # "wherever you started"

通过使用上下文管理器,您将成为异常并返回值安全的:即使您从上下文块内部抛出异常或返回,您的代码也将始终cd回到其起始位置。

也可以在嵌套块中嵌套pushd调用,而不必依赖全局目录堆栈:

with pushd('somewhere'):
    # do something
    with pushd('another/place'):
        # do something else
    # do something back in "somewhere"

我不认为您可以在一个os.system()调用中调用pushd

>>> import os
>>> ret = os.system("pushd /tmp")
sh: pushd: not found

也许你的系统实际上提供了一个触发shell内部函数的pushd二进制文件(我想我以前在FreeBSD上见过),但是进程的当前工作目录不受其他进程的影响,所以你的第一个system()启动了一个shell,运行了一个假设的pushd,启动一个shell,运行ls,启动一个shell,运行一个假设的popd。。。这些都不会互相影响。

您可以使用os.chdir("/home/path/")更改路径:http://docs.python.org/library/os.html#os-file-dir

每个shell命令在单独的进程中运行。它生成一个shell,执行pushd命令,然后shell退出。

只需在同一个shell脚本中编写命令:

os.system("cd /directory/path/here; run the commands")

一个更好的方法是使用^{}模块:

from subprocess import Popen
Popen("run the commands", shell=True, cwd="/directory/path/here")

相关问题 更多 >