私は crontab を使用して、Minecraft サーバーのメンテナンス スクリプトを実行しています。crontab が再起動スクリプトを使用しようとしない限り、ほとんどの場合は正常に動作します。再起動スクリプトを手動で実行する場合、問題は発生しません。パス名に関係していると思うので、Minecraft コマンドが常に Minecraft ディレクトリから実行されるようにしています。そのため、コマンドを pushd/popd で囲んでいます。
os.system("pushd /directory/path/here")
os.system("command to sent to minecraft")
os.system("popd")
以下は、Minecraft を除いた対話型セッションです。単純な「ls」テストです。ご覧のとおり、os.system コマンドは pushd ディレクトリからではなく、私の論点を説明するために Python を実行していたディレクトリである /etc/ から実行されます。明らかに pushd は 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
=== (Python 2.4 を搭載した CentOS サーバー)
ベストアンサー1
Python 2.5 以降では、次のようにコンテキスト マネージャーを使用する方がよいと思います。
import contextlib
import os
@contextlib.contextmanager
def pushd(new_dir):
previous_dir = os.getcwd()
os.chdir(new_dir)
try:
yield
finally:
os.chdir(previous_dir)
次のように使用できます。
with pushd('somewhere'):
print os.getcwd() # "somewhere"
print os.getcwd() # "wherever you started"
コンテキスト マネージャーを使用すると、例外と戻り値が安全になります。コンテキスト ブロック内から例外をスローしたり戻ったりした場合でも、コードは常に開始した場所に戻ります。
グローバル ディレクトリ スタックに依存せずに、ネストされたブロック内に pushd 呼び出しをネストすることもできます。
with pushd('somewhere'):
# do something
with pushd('another/place'):
# do something else
# do something back in "somewhere"