gpt4 book ai didi

python - 在 Python 中,自定义文件描述符如何用于输入和输出,包括默认设置和最终关闭?

转载 作者:太空狗 更新时间:2023-10-29 12:25:02 36 4
gpt4 key购买 nike

我想了解自定义文件描述符如何在 Python 中用于输入、输出、默认设置和最终关闭。我在 Bash 中有一个文件,它完全可以执行我想在 Python 中执行的操作。谁能告诉我这将如何在 Python 中完成?我正在使用 Python 2.7.5、Bash 4.2,并在 CentOS 7.3 上执行。

设置

$ echo "input string" > input

bash_fd.sh

#!/bin/bash

# Demonstration of custom file descriptors in Bash
# 3 script input (scrin)
# 4 script output (scrout)
# 5 script error (screrr)
# 6 script data (scrdata, demo: JSON return payload)
# 7 script log (scrlog)

fd_open()
{
### Provide defaults for file descriptors 3-7 ONLY if the FDs are undefined
{ >&3; } 2>/dev/null || exec 3<&0 # dup scrin to stdin
{ >&4; } 2>/dev/null || exec 4>&1 # dup scrout to stdout
{ >&5; } 2>/dev/null || exec 5>&2 # dup screrr to stderr
{ >&6; } 2>/dev/null || exec 6>/dev/null # set scrdata to /dev/null
{ >&7; } 2>/dev/null || exec 7>/dev/null # set scrlog to /dev/null
}

fd_close()
{
# Close all file descriptors
exec 3>&-
exec 4>&-
exec 5>&-
exec 6>&-
exec 7>&-
}

main()
{
fd_open # Ensure

echo "[$(date)] Program beginning" >&7 # scrlog

echo -n 'Enter a message: ' >&4 # scrout
read MSG <&3 # scrin

echo "Read message $MSG" >&4 # scrout
echo "[screrr] Read message $MSG" >&5 # screrr

echo "{\"msg\": \"$MSG\"}" >&6 # scrdata: return JSON payload
echo "[$(date)] Program finishing: $MSG" >&7 # scrlog

fd_close

return ${1:-0} # return status code
}

# For demonstration purposes, $1 is the return code returned when calling main
main "$1"

调用

$ ./bash_fd.sh 37 3<input 4>scrout 5>screrr 6>scrdata 7>scrlog
$

返回码

$ echo $?
37

生成的文件

$ cat scrout
Enter a message: Read message input string

$ cat screrr
[screrr] Read message input string

$ cat scrdata
{"msg": "input string"}

$ cat scrlog
[Wed Jun 14 21:33:24 EDT 2017] Program beginning
[Wed Jun 14 21:33:24 EDT 2017] Program finishing: input string

将上述 Bash 脚本翻译成 Python 的任何帮助都将真正帮助我理解 Python 和自定义文件描述符,我们将不胜感激。

最佳答案

Python 2 的 file objectC's stdio FILE structure 的一个相当薄的包装,它本身包含相应的描述符(一个整数)。在许多地方,文档都引用了底层/相关的 stdio,这并非巧合。东西。

  • 每次您创建文件对象 ( open() ) 时,都会打开一个对应于该文件的描述符,并将其用于该对象的所有 I/O 操作。

    • 你可以用 <file>.fileno() 得到它.
    • 相反,如果你有一个原始描述符,你可以用 os.fdopen() 的文件对象包装它.
      • 例如如果你命令 bash重定向脚本的特定描述符,它已为您的子进程打开相应的描述符。
  • 当文件对象被关闭或垃圾回收时,底层描述符也被关闭。

  • os module还有一些其他函数可以与描述符一起使用,这些描述符反射(reflect)了相应的 C 函数,例如 os.dup() .

通常,您应该使用文件对象,不要理会它们的底层描述符。即使使用返回原始描述符的函数,您也可以这样做 like with os.pipe() .


例子:

(尖括号中的实体是伪代码,表示要插入的内容)

检查描述符是否存在:

同时 How to check if a given file descriptor stored in a variable is still valid?建议(仅限 UNIX)fcntl或(可移植)dup作为侵入性最小的方式,因为您将通过文件对象使用它,it's best to just attempt to :

import os,errno    
<...>
try: f = os.fdopen(<fd>)
except OSError as e:
if e.errno!=errno.EBADF: raise
else:
# actions when doesn't exist, maybe create `f' some other way
else:
#actions when exists
# use `f'

重复的 FD

不是真的需要 - 你可以分配例如f = sys.stdin根据条件和用途 f . 您真正需要它的唯一情况是您必须向其他进程提供额外的 FD。

例如复制文件对象的 FD 并在副本上创建另一个文件对象:

os.dup2(old_f.fileno(),<new_fd>)
new_f = os.fdopen(<new_fd>)

读取/写入/关闭一个 FD

读取/写入/关闭/任何包装该 FD 的文件对象。参见 Reading and Writing files - Python tutorial , 唯一的区别是如果你有一个原始的 FD,你用 os.fdopen() 创建文件对象而不是 open() .

关于python - 在 Python 中,自定义文件描述符如何用于输入和输出,包括默认设置和最终关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44557281/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com