【问题标题】:bash or python script to read binary data from STDIN and save to a filebash 或 python 脚本从 STDIN 读取二进制数据并保存到文件
【发布时间】:2016-04-02 16:38:01
【问题描述】:

在任何人告诉我之前,我已经完全意识到我正在尝试做的事情是荒谬的,但我有我的理由。

我有一个服务器,我可以在上面编写脚本(bash 或 python)。该脚本需要接受来自 STDIN 的二进制数据并将其保存到文件中。准确地说,二进制数据是一个WAV文件。

我正在使用一个名为 Workflow 的 iOS 应用程序。该应用程序将让我录制音频文件,然后将其作为 STDIN 输入发送到它将通过 SSH 运行的脚本。所以我的脚本需要接受该 STDIN 输入并将其保存到文件中。

有什么想法/想法吗?我完全不知道从哪里开始。

【问题讨论】:

标签: python bash ssh binary stdin


【解决方案1】:

将标准输入保存到 POSIXy 系统上的文件中:

  1. 确保标准输入以二进制模式打开
  2. 检查fadvise 是否在您的情况下提高了时间性能,例如,请参阅copyfileobj() in contrib
  3. 从标准输入读取块并将它们写入文件

一般来说,您也可以try os.sendfile() if stdin might be redirected from a file (mmap-able file descriptor)(不适用于您的情况)。

#!/usr/bin/env python
import os
import shutil
import sys

with os.fdopen(sys.stdin.fileno(), 'rb') as input_file,\
     open(sys.argv[1], 'wb') as output_file:
    shutil.copyfileobj(input_file, output_file)

例子:

$ python -msave_stdin output_file

应该相当于:

$ cat >| output_file

【讨论】:

  • 请注意,这会关闭 STDIN 的文件描述符,这可能会导致问题。为避免这种情况,不要使用“with”上下文打开“stdin”,而是:input_file = os.fdopen(sys.stdin.fileno(), 'rb')
  • 对,复制成功但STDIN(文件描述符0)已关闭。在block前后执行os.system(f'ls -la /proc/{os.getpid()}/fd'),你就会明白我的意思了。关闭 FD=0 的(长时间运行的)程序可能会遇到奇怪的事情。一个例子是,如果你之后打开一个文件,它可能会得到 FD=0,因为它是免费的。如果我们不小心并假设 FD=0 始终是“stdin”,我们可能会感到困惑。
【解决方案2】:

在 python 中从标准输入读取:

import sys
input = sys.stdin.read()

将二进制写入文件:

with open('name_of_file_here','wb') as output:
   output.write(input)

'wb' 以二进制模式发送写入的位置。

【讨论】:

  • 我应该提到,read() 函数将读取来自标准输入的所有内容,直到遇到 EOT,即 \x04(十六进制)或 Ctrl+D。为了安全起见,您可以检查要通过管道传输到标准输入的字节数,然后使用 sys.stdin.read(number_of_bytes)
  • 你说的是Windows吗?在 Windows 上管道二进制数据是一项不平凡的任务,例如,请参阅what happens in PowerShell。在 POSIX 上管道二进制数据是微不足道的(它不会在 \x04 或其他任何地方停止 - 不要混淆您在终端中键入的内容(可能受终端设置影响)和通过应用程序的标准输入管道传输的数据)。
  • 我说的是 POSIX。刚刚测试它,你是绝对正确的。不知道为什么我这么认为...谢谢!
  • 为了避免损坏换行符(如果os.linesep != b'\n')或为了兼容 Python 3,请以二进制模式打开标准输入。要支持大文件,请分块读取标准输入。
猜你喜欢
  • 2010-12-30
  • 2021-03-23
  • 2014-10-18
  • 1970-01-01
  • 2013-08-22
  • 2023-03-13
  • 2018-07-05
  • 2010-12-17
相关资源
最近更新 更多