【问题标题】:how can you Import an os variable into PYTHON and have it update?如何将 os 变量导入 PYTHON 并对其进行更新?
【发布时间】:2015-02-27 09:34:21
【问题描述】:

我正在尝试找到一种方法来轻松干净地从外部操作系统输入关闭我的代码。我有一个在 beaglebone black 或 BBB 上运行的 python tcp 服务器,等待 tcp/ip 通信告诉它通过 gpio 输出打开和关闭继电器,它工作得很好,我编写了一个 Windows 程序来远程控制它。我的问题是 python 相关的,而不是 BBB 相关的。我为 tcp/ip 服务器接口运行了这个脚本,当我更新 linux 环境变量“pyserv”时,脚本没有得到更新,它只知道程序启动时 pyserv 的值。故障码直接在下方。

    while True:
        pyserv = os.environ.get('pyserv')
        if pyserv == "1":
            server.socket.close()
            break

但是,在我启动脚本之前,我可以将环境变量更改为 0,然后它就会运行。或者,我可以将其设置为 1 并立即关闭。如果我启动脚本然后更改环境变量,它不会得到更新。我还尝试将此代码插入 vardata.py 并导入 vardata.py 的值。我有同样的结果。下面我在上下文中有完整的代码。问题代码在最底部。

#!/usr/bin/env python

import sys
import threading
import SocketServer
import os
import Adafruit_BBIO.GPIO as GPIO

GPIO.setup("P8_14", GPIO.OUT)
s1 = 0
class ThreadedEchoRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        global s1
        # self.request is the TCP socket connected to the client
        self.data = self.request.recv(1024).strip()
        cur_thread = threading.currentThread()
        print self.data
        if self.data == "1":
            if s1 == 0:
                GPIO.output("P8_14", GPIO.HIGH)
                s1 = 1
            elif s1 == 1:
                GPIO.output("P8_14", GPIO.LOW)
                s1 = 0
        response = '%s: %s' % (cur_thread.getName(), self.data)
        self.request.send(response)
        return

class ThreadedEchoServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

if __name__ == '__main__':
    import socket
    import threading

    HOST, PORT = "", 9999

    # Create the server, binding to localhost on port 9999
    server = SocketServer.TCPServer((HOST, PORT), ThreadedEchoRequestHandler)

    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    t = threading.Thread(target=server.serve_forever)
    t.setDaemon(True) # don't hang on exit
    t.start()
    print 'Server loop running in thread:', t.getName()

### This Is Where The Code That Is Giving Me Issue's lies. ###
        while True:
        pyserv = os.environ.get('pyserv')
        if pyserv == "1":
            server.socket.close()
            break
### This Is Where The Code That Is Giving Me Issue's lies. ###

【问题讨论】:

  • 你是如何改变环境变量的?
  • 我希望最终有一个 bash 脚本来控制一切并作为后台服务运行,但目前我正在使用 export pyserv=1 对其进行测试
  • 环境变量不是 IPC 的机制。在每个操作系统中发生的情况是,当创建一个新进程时,它会从正在执行的进程中复制环境变量,仅此而已。你应该想办法做到这一点,最简单的是创建删除文件。
  • 谢谢 itai,实际上我的脚本是用这一行代替的。 from vardata import pyserv 然后我会将 vardata.py 更改为 pyserv = 1pyserv = 0 并且有同样的问题。它不会响应我对文件所做的任何更改。

标签: python linux import environment-variables tcplistener


【解决方案1】:

只需使用纯文本文件来存储您的 pyserv 数据。

首先创建 pyserv 数据文件。例如,

echo 1 > vardata

现在运行这个:

test1.py

#! /usr/bin/env python
import time

def get_data(fname):
    with open(fname, 'r') as f:
        return int(f.read())

while True:
    time.sleep(1)
    pyserv = get_data('vardata')
    print pyserv

点击 Ctrl+C 中止脚本。

如果您更改vardata 的内容,它将反映在脚本输出中。

这比将参数存储在可执行 Python 文件中更简单(也更安全)。但是,如果您确实想为参数使用 Python 文件,那么您需要脚本重新加载导入的数据以使任何更改可见。

vardata.py

pyserv = 1

test2.py

#! /usr/bin/env python
import time
import vardata

while True:
    time.sleep(1)
    reload(vardata)
    print vardata.pyserv

注意你必须做import vardata;如果你这样做 from vardata import pyserv reload() 调用将失败。

【讨论】:

  • 正确的方法。基本上,您无法从正在运行的进程(在这种情况下为 python 脚本)读取更新的 env,因此您需要创建一个新进程(重复读取文件),该进程将使用当前 env 变量生成。
  • 谢谢 PM 2Ring,这正是我想要的,我实际上也尝试过重新加载但失败了,现在我知道为什么重新加载不起作用了。然而,说到底,我还是使用了你提到的def get_data(fname): with open(fname, 'r') as f: return int(f.read()) 方法从文件中读取数据。稍后我可能会对其进行更改,但这目前效果很好,并且我可以在关闭脚本之前进行清理,而不是运行 killall 并将事情卡在错误的状态。
  • @Cfoote7:我的荣幸!使用纯文件的一件可爱的事情是int(f.read()) 会忽略数字前后的空格,因此您不必对写入文件的方式过于挑剔。但是,如果您想在文件中存储多个项目,那么采用某种文件结构可能是个好主意,例如 CSV、JSON,或者如果您非常热衷于 XML。
猜你喜欢
  • 1970-01-01
  • 2022-11-20
  • 2015-09-18
  • 1970-01-01
  • 2013-12-12
  • 2019-03-04
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
相关资源
最近更新 更多