✏️
blog
  • README
  • 2023 11
    • expect使用
  • 2023 10
    • 通过Appium给iOS应用自动化执行脚本
  • 2023 06
    • 三种ThreadLocal详解
    • 常见限流算法总结
    • 分布式ID生成算法
  • 2023 05
    • 线上机器CLOSE_WAIT连接数异常排查
    • 多数据源引发transactional事务回滚失效
  • 2023 04
    • MySQL中BufferPool
  • 2022 12
    • Linux IO
    • Netty总结
  • 2022 04
    • Thrift
  • 2022 03
    • JVM命令总结
    • 频繁FullGC定位思路
    • Redis总结
    • Spring常见问题总结
    • Kafka总结
  • 2022 02
    • Dubbo柔性服务天池大赛总结
  • 2021 12
    • 泛型中的extends和super
    • 手写一个Spring Boot Starter
  • 2021 11
    • 常用消息队列总结
  • 2021 10
    • swagger2快速使用
    • SpringBoot接口cors跨域访问
  • 2021 08
    • 常用shell命令总结
  • 2021 05
    • 线程cpu飙升排查
    • zookeeper install
  • 2021 04
    • Java虚拟机
    • [Spring Boot](2021-04/2021-04-04-Spring Boot.md)
    • [Spring MVC](2021-04/2021-04-04-Spring MVC.md)
    • 分布式ID
    • 消息队列
    • [Spring AOP](2021-04/2021-04-05-Spring AOP.md)
    • 布隆过滤器
    • Scala内核Spark阻塞排查
  • 2020 12
    • 使用Python优雅实现tail命令
  • 2020 11
    • Spark基础架构
    • 一文搞定Git
    • Spark线上问题引发的思考
  • 2020 04
    • 使用GitBook
  • 2019 05
    • SELinux、Netfilter、iptables、firewall和ufw五者关系
    • 安装npm和nodejs
    • 访问不到云服务器中的项目
  • 2019 04
    • 二叉树中节点与度数
    • 实现会话跟踪的技术有哪些
    • 计算机操作系统-死锁
    • Semaphore Count Down Latch Cyclic Barrier
    • Java内存模型
    • 双重检查锁定
    • synchronized实现底层
    • Lock接口
    • HTTP与HTTPS的区别
    • Java中线程池
    • Java中的阻塞队列
    • 排序算法
  • 2019 03
    • MySQL中索引
    • MySQL存储引擎
    • MySQL锁机制
    • n的阶乘结果后面0的个数
由 GitBook 提供支持
在本页

这有帮助吗?

  1. 2020 12

使用Python优雅实现tail命令

class CmdOutputHandler(IPythonHandler):
    async def post(self):
        data = self.get_json_body()
        cmd = data['cmd']
        proc = await asyncio.create_subprocess_exec(cmd[0], *cmd[1:], stdout=asyncio.subprocess.PIPE)
        await asyncio.wait_for(proc.wait(), timeout=10)
        output = await proc.stdout.read()
        self.finish({'output': output.decode('utf-8')})
import errno
import os


# read at least n lines + 1 more from the end of the file,like /usr/bin/tail
def tail(filename, n, bsize=2048):
    # get newlines type, open in universal mode to find it
    with open(filename, 'rU') as f:
        if not f.readline():
            return
        sep = f.newlines
    assert isinstance(sep, str), 'multiple newline types found, aborting'
    sep_bytes = sep.encode('UTF-8')

    line_count = 0
    pos = 0
    with open(filename, 'rb') as f:
        f.seek(0, os.SEEK_END)

        while line_count <= n + 1:
            # read at least n lines + 1 more; we need to skip a partial line later on
            try:
                f.seek(-bsize, os.SEEK_CUR)
                line_count += f.read(bsize).count(sep_bytes)
                # after f.read() offset will incr bsize, so we need go back again
                f.seek(-bsize, os.SEEK_CUR)
            except IOError as e:
                if e.errno == errno.EINVAL:
                    bsize = f.tell()
                    f.seek(0, os.SEEK_SET)
                    pos = 0
                    line_count += f.read(bsize).count(sep_bytes)
                    break
                raise e
            pos = f.tell()

    def read_last_lines(count=line_count):
        # Re-open in text mode
        with open(filename, 'r') as f:
            f.seek(pos, os.SEEK_SET)  # our file position from above

            for line in f:
                # We've located n lines *or more*, so skip if needed
                if count > n:
                    count -= 1
                    continue
                # The rest we yield
                yield line

    return ''.join(read_last_lines(line_count))
上一页2020 12下一页2020 11

最后更新于4年前

这有帮助吗?