私信  •  关注

larsks

larsks 最近创建的主题
larsks 最近回复了
1 年前
回复了 larsks 创建的主题 » 在Linux下,使用子进程查询Git状态会引发错误

当你设定 shell=True , subprocess 使用 /bin/sh .在Ubuntu上, /垃圾箱/垃圾箱 不是Bash,而是使用特定于Bash的语法( [[...]] ).你可以明确地向 bash 相反:

subprocess.check_output(["/bin/bash", "-c", "[[ -z $(git status -s) ]] && echo 'clean'"]).strip()

但现在还不清楚为什么要在这里使用shell脚本:只需运行 git status -s 使用Python,并自行处理结果:

out = subprocess.run(['git', 'status', '-s'], stdout=subprocess.PIPE)
if not out.stdout:
  print("clean")

这是一个 formatted string literal ,在Python 3.6中引入。反斜杠需要在字符串中转义,否则它们会被解释为转义序列(例如。, \n , \t ).

作者本可以使用格式化的原始字符串( fr'...' ),就像这样:

fr'^\s*{args.comment}'

在原始字符串中,反斜杠没有特殊含义,因此可以逐字使用。

2 年前
回复了 larsks 创建的主题 » docker compose-无法连接到postgres db

Postgres需要一段时间才能启动,然后才能开始为请求提供服务。您的代码可能在 test 容器正在尝试在Postgres准备就绪之前连接。

最好的选择可能是在集成测试中添加一些重试逻辑。例如,在你的简历中添加一些东西 setup method 循环,直到能够建立成功的数据库连接。

2 年前
回复了 larsks 创建的主题 » 如何使用python从git存储库获取特定的文件版本

当你要求 commit.tree / 'dataset.xlsx' ,你会得到一个 git.Blob 对象:

>>> targetfile
<git.Blob "3137d9443f54325b8ad8a263b13053fee47fbff2">

如果要读取对象的内容,可以使用 data_stream 方法,该方法返回类似文件的对象:

>>> data = targetfile.data_stream.read()

或者你可以使用 stream_data 方法(不要看我,我没有给它们命名),该方法将数据写入类似文件的对象:

>>> import io
>>> buf = io.BytesIO()
>>> targetfile.stream_data(buf)
<git.Blob "3137d9443f54325b8ad8a263b13053fee47fbff2">
>>> buf.getvalue()
b'The contents of the file...'
2 年前
回复了 larsks 创建的主题 » Docker py如何使用from_env()从容器访问Docker主机

默认情况下,容器将无法访问主机Docker服务(这是一项安全功能:访问Docker与 root 访问权限,因此您只希望在特定情况下公开此访问权限)。

如果要从容器中访问主机的Docker服务,需要将Docker套接字映射到容器中。一般来说,这意味着运行以下操作:

docker run -v /var/run/docker.sock:/var/run/docker.sock ...

比较:

$ docker run --rm -it docker.io/python:3.10 bash
$ pip install docker
[...]
$ python
root@2dfed359374e:/# python
Python 3.10.3 (main, Mar 18 2022, 16:01:59) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import docker
>>> c = docker.from_env()
Traceback (most recent call last):
[...]
FileNotFoundError: [Errno 2] No such file or directory

有了这个:

$ docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock docker.io/python:3.10 bash
root@ebe430bc9463:/# pip install docker
[...]
root@ebe430bc9463:/# python
Python 3.10.3 (main, Mar 18 2022, 16:01:59) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import docker
>>> c = docker.from_env()
>>> c.containers.list()
[<Container: ebe430bc94>, <Container: 91f24628fd>]
2 年前
回复了 larsks 创建的主题 » 当Python3中没有跳过输入的选项时,如何绕过输入提示?

一个解决办法是 monkey patch 图书馆将暂时替换 input 作用例如,如果我有一个模块 foo.py 看起来是这样的:

def take_action():
    print("doing something")


def foo():
    if input("Proceed? ") == "yes":
        take_action()

我会写字 bar.py 这样地:

import foo
from unittest import mock


def fake_input(default_response=None):
    '''Creates a replacement for the `input` function that will
    return a default response if one was provided.'''

    def _input(prompt):
        return default_response if default_response else input(prompt)

    return _input


with mock.patch("foo.input", new=fake_input("yes")):
    foo.foo()

foo.foo()

如果运行此代码,您将看到 foo.foo() 使用默认输入,无需提示即可继续。第二个电话 到 福。foo() 将正常提示。

2 年前
回复了 larsks 创建的主题 » 将docker卷导出到另一台机器

首先,请注意 docker export 与体积无关;该命令导出一个 容器 文件系统作为tar归档。这不包括已装入卷中的任何内容。

docker run -v postgresql_data:/data alpine tar -C /data -cf- . |
  ssh remotehost docker run -i -v postgresql_data:/data alpine tar -C /data -xf-

这会对现有卷中的所有内容进行tar,并通过ssh连接将其传输到远程主机,在那里我们创建一个新的postgresql_数据容器,并通过提取tar存档来填充它。

特别是对于博士后,你可以 pg_dump pg_restore 而不是使用 tar .

您将不得不修改容器名称,因为您正在使用 docker-compose .

5 年前
回复了 larsks 创建的主题 » 用户应该有哪些权限公开docker容器端口?

传统上只有 root 里面 port publishing 机制。

对于您的示例,您可以将服务配置为侦听端口80以外的其他端口…对于本示例,假设您将其配置为侦听端口8080。

运行容器时,请将主机上的端口80映射到容器中的端口8080:

docker run -p 80:8080 ...

现在您可以在主机的80端口访问您的服务。你可以用同样的方法处理443端口。

EXPOSE Dockerfile中的关键字在很大程度上是不必要的。在一个典型的Docker环境中,它是一个无操作的,只提供信息的环境。您可以发布端口,无论是否 暴露 d。

[1] 事实上 a little more nuanced 在Linux下。

4 年前
回复了 larsks 创建的主题 » Docker使用卷共享环境变量

通常,您是通过显式地向其他容器提供相同的环境变量来实现的。如果你用的是 docker-compose.yml

version: 3

services:
  database:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD

  frontend:
    image: webserver
    environment:
      MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD

如果你设置了 MYSQL_ROOT_PASSWORD .env 文件,将为两个 database frontend 集装箱。如果你不使用 docker-compose database.env 包含:

MYSQL_ROOT_PASSWORD=secret

docker run --env-file database.env ... .


文件夹 . 因此,另一种选择是让数据库容器将包含密码的文件写入共享卷,然后在其他容器中读取。

4 年前
回复了 larsks 创建的主题 » 如何测试通过git对python库所做的更改?

pip可以安装我的自定义/修改版本的库吗?

解决这个问题有多种方法。一个常见的解决方案是使用Python virtual environments . 这允许您创建一个独立的Python环境,该环境与您的系统Python安装不共享相同的包。然后,您可以在其中安装一些东西(比如修改后的Python库)来测试它。

要开始,你需要 virtualenv 工具。这可能作为分发版的软件包提供,但也可以使用 pip . 一旦拥有它,就可以在与代码相同的目录中运行:

virtualenv .venv

这将创建一个名为 .venv . 你想叫什么就叫什么,但要命名 (或任何以 . )意味着它不会干扰 ls 在你的工作区。

. .venv/bin/activate.sh

这将修改您的 $PATH 将virtualenv放在目录列表的前面。现在当你打字的时候 python ,您将使用virtualenv版本。

如果你的代码有 setup.py 文件,可以按如下方式安装:

pip install -e .

这个 -e

完成后,您可以运行:

deactivate

这将删除 activate


有关详细信息:

5 年前
回复了 larsks 创建的主题 » docker编写只读绑定卷合并

我认为您不能避免这种行为:Docker需要创建文件系统条目,它可以将绑定挂载附加到 test/... 坐骑。如果绑定安装文件,则文件必须首先存在于目标位置;类似于目录。

这意味着在执行绑定挂载之前,Docker首先创建一个新的(空的)文件或目录来提供挂载的目标。这就是你看到的 app 目录。

您的选择是(a)只与它一起生活,或者(b)重构您的项目,这样您就不需要将装入的东西绑定到现有的绑定安装中。

5 年前
回复了 larsks 创建的主题 » python-读取每x行

这是我建议的一个例子。这个过程是标准的, 向五个工人的集合发送线路。第一个工人会 得到0、5、10、15等线,第二个工人得到1、6、11、16, 等等等等。

import itertools
import queue
import sys
import threading


class Worker(threading.Thread):
    def __init__(self, id, q, **kwargs):
        self.id = id
        self.q = q
        super().__init__(daemon=True, **kwargs)

    def run(self):
        while True:
            # Receive another (line_number, line) tuple from the
            # main thread.
            ln, line = self.q.get()
            if ln == -1:
                break

            print('thread {} processing line {}: {}'.format(self.id, ln, line))


def main():
    workers = []
    queues = []

    # create workers, and for each worker create a queue that will
    # be used to pass data to the worker.
    for i in range(5):
        q = queue.Queue()
        w = Worker(i, q)
        workers.append(w)
        queues.append(q)
        w.start()

    # create a "cycle": an infinite iterator that will loop over
    # the list of queues.
    q_cycle = itertools.cycle(queues)
    for ln, line in enumerate(sys.stdin):
        q = next(q_cycle)
        q.put((ln, line))

    # tell the workers to exit
    for q in queues:
        q.put((-1, None))

    # wait for workers to finish
    for w in workers:
        w.join()


if __name__ == '__main__':
    main()
5 年前
回复了 larsks 创建的主题 » 为什么不能使用Expect脚本启动redis?

您希望第一个示例做什么?你以一个 interact 语句,将控制台连接到生成的进程中的stdin/stdout。这个 redis-server 程序不是交互式的:它不接受任何控制台输入。当你跑步时 ReDIS服务器 ,它将达到…

1135:M 18 Nov 13:59:51.634 * Ready to accept connections

…然后它停止,等待redis客户机连接并对其进行操作。另外,请注意,我使用的Redis版本以结尾 Ready to accept connections 而不是 The server is now ready to accept connections ,所以我将在下面的示例中使用它。

我们可以添加一个 puts 命令到Expect脚本,以查看它不是 在任何地方都会被卡住。如果我运行以下程序:

#!/usr/bin/expect -f
spawn redis-server
expect "Ready to accept connections"
puts "redis is running"
interact

我得到输出:

spawn redis-server
1282:C 18 Nov 14:03:33.123 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1282:C 18 Nov 14:03:33.123 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=1282, just started
[...]
1282:M 18 Nov 14:03:33.124 * Ready to accept connections
redis is running

所以我们可以看到它不会被卡在 spawn 语句, 甚至不在 expect 语句。

你的问题不清楚的是你为什么要使用 期待 在这种情况下,因为 ReDIS服务器 不是交互式程序 不会产生任何需要自动化的提示。