stdout, stdin, stderr的区别

2023-05-16

stdin, stdout,stderr的中文名字分别是标准输入,标准输出和标准错误。

当一个用户进程被创建的时候,系统会自动为该进程创建三个数据流, 一个程序要运行,需要有输入、输出,如果出错,还要能表现出自身的错误。这就是要从某个地方读入数据、将数据输出到某个地方,这就够成了数据流。

因此,一个进程初期所拥有的这三个数据流即为标准输入、标准输出和标准错误,分别用stdin, stdout, stderr来表示。这3个文件分别为标准输入(stdin)、标准输出(stdout)、标准错误(stderr)。大多数环境中,stdin指向键盘,stdout、stderr指向显示器。之所以使用stderr,是因为一般来讲,若因某种原因造成其中一个文件无法访问,相应的诊断信息要在该程序运行输出信息的末尾才能打印出来。当输出到屏幕时,这种处理方法尚可接受,但如果诊断信息输出到一个文件或通过管道输出到另一个程序时,就无法接受了。若有stderr存在,即使对标准输出进行了重定向,也只有stdout的信息会写入重定向文件,而stderr中的输出还是显示在屏幕上。

sys.stdin 介绍

sys.stdin提供了read()和readline()函数,如果想按一行行来读取,可以考虑使用它:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()

注意:如果没有数据,io会被堵塞,所以可以对标准输入做数据检查(Linux):
···
import sys
import select

if select.select([sys.stdin], [], [], 0.0)[0]:
help_file_fragment = sys.stdin.read()
else:
print(“No data”, file=sys.stderr)
sys.exit(2)
···
此外,python还提供input()函数可以进行数据输入,但两者有区别,input()会把末尾的‘\n’忽略:

>>> a = input("请输入一个数字:")
请输入一个数字:20
>>> a

而stdin.readline()默认输入的格式是字符串,如果输入的是int,float类型则会强制转换成字符串类型,且会将标准输入全部获取,包括末尾的’\n’。

sys.stdin 还可以与print合用产生input的效果:

import sys
print('Please input your name: ')
name = sys.stdin.readline()
print('Hello ', name)

输出结果:
Please input your name: 
Hello 

这里可以看到,尽管在print('Hello ', name)里,name在后面,但是在显示的时候会出现在前面。

sys.stdout与sys.stderr 介绍

在默认情况下,stdout是行缓冲的,他的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。stderr是不带缓冲的,这使得出错信息可以直接尽快地显示出来。

sys.stdout 还可将标准输出重新定向到指定文件:

import sys
sys.stdout = open('log', 'a')
b = print('haha', file=sys.stdout)

运行代码后打印信息不会在屏幕上显示,而是会写到log文件中

sys.stderr 则可将标准错误信息重定向输出到错误文件中:

import sys
sys.stdout = open('errlog', 'a')
b = print('haha', file=sys.stdout)

运行代码后错误信息不会在屏幕上显示,会写入到errlog文件中
在linux中可以不用指定sys的stdout和stderr文件,若运行:

python test.py >log 2>errlog

这样打印信息会在log文件中,错误信息会展示到errlog文件中。这里的2表示标准错误信息流,>errlog表示将结果打印到errlog文件中。

此外,我们还可以结合logging模块的操作通过指定handler来控制屏幕信息输出:

#test.py
import logging
import sys
logger1=logging.getLogger("logger1")
handler1 = logging.StreamHandler(sys.stderr)
formatter1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler1.setFormatter(formatter1)
logger1.addHandler(handler1)

logger2=logging.getLogger("logger2")
formatter2 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler2 = logging.StreamHandler(sys.stdout)
handler2.setFormatter(formatter2)
logger2.addHandler(handler2)
logger2.setLevel(level=logging.INFO)`

logger1.info("not output because of level")
logger1.warning("output in red")#标准错误输出在notebook中输出是红色的。
logger2.info("output in white")
logger2.warning("output in white")#标准正常输出是白色的。

输出结果为:

2022-07-28 15:25:56,570 - logger1 - WARNING - output in red
2022-07-28 15:25:56,575 - logger2 - INFO - output in white
2022-07-28 15:25:56,577 - logger2 - WARNING - output in white

如果进行重定向,python test.py >log 2>errlog,则第一条logger1的输出结果存入errlog文件,其余logger2的输出结果存入log文件。

sys.stdout.write方法

sys.stdout还有一个write方法,调用的是 file 对象的 write 方法,区别是 file 对象的 write 方法把字符写入到文件中,sys.stdout.write 方法把字符写入到标准输出中,也就是控制台。这一点上与print()方法类似,但是stdout.write 默认不换行,print 默认换行

import sys
print('print 默认换行')
sys.stdout.write('stdout.write 默认不换行')
print('+++++++++')

输出结果:
print 默认换行
stdout.write 默认不换行+++++++++

因此stdout.write 需配合 \n 换行符实现换行功能:

sys.stdout.write('str \n')

print也可以实现不换行:

print('str', end='')

此外,print 几乎可以打印所有的对象,而 stdout.write 只能接受 str 类型。

import sys
class name():
    def __str__(self):
        return 'Citizen_Wang'
a = name()

print(a)
print(type(a))
sys.stdout.write(a)

此脚本会报错:
TypeError: write() argument must be str, not name

解决方法:
sys.stdout.wirte(str(a))

sys.stdout还可以与print结合使用:

import sys
file = sys.stdout    # 存储原始的输出对象
sys.stdout = open('1.txt', 'w')  # 重定向所有的写入内容到 1.txt 文件
print('Citizen_Wang')   # 写入到 1.txt 文件中
print('Always fall in love with neighbours')  # 继续写入到文件中
sys.stdout.close()    # 其实就是 open 文件之后的关闭
sys.stdout = file  # 将 print 命令的结果返回给控制台
print('输出信息返回在控制台')  # 该信息会在控制台也显示

以上代码会在当前目录下创建了一个 1.txt 文件,内容如下:

Citizen_Wang
Always fall in love with neighbours
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stdout, stdin, stderr的区别 的相关文章

  • 对 stdin、stdout 和 stderr 感到困惑吗?

    我对这三个文件的用途感到相当困惑 如果我的理解是正确的话stdin是程序写入其请求以在进程中运行任务的文件 stdout是内核将其输出写入其中的文件 并且请求它的进程从中访问信息 并且stderr是输入所有异常的文件 在打开这些文件以检查这
  • 如何重定向 python 中函数的打印输出[重复]

    这个问题在这里已经有答案了 可能的重复 我可以将 python 中的标准输出重定向到某种字符串缓冲区吗 https stackoverflow com questions 1218933 can i redirect the stdout
  • 如何写入 stdIn (JAVA) [重复]

    这个问题在这里已经有答案了 我想通过使用一些输入 例如 join 8 对我的 P2P 系统进行一些测试 8 是节点号 对于我的系统 命令 join 8 是从标准输入读取的 但我不想将其键入数百次以进行数百次测试 因此我编写了一个测试函数来随
  • C/C++ - 运行系统(“process &”),然后写入其标准输入

    我正在研究 Linux 和 C C 我编写了一个带有一些线程的程序 include pthread h 并使用 sudo 运行它 一个线程运行一个进程 mplayer 并通过添加 使其保持运行 以便system 可以快速返回 system
  • 使用子进程 PIPE 在 Python 脚本之间发送字符串

    我想在我的主 python 程序中使用子进程打开一个 Python 脚本 我希望这两个程序能够在运行时相互聊天 这样我就可以监视从属脚本中的活动 即我需要它们在彼此之间发送字符串 主程序将具有与此类似的功能 它将与从属脚本进行通信并监视 S
  • 输出字符串末尾的空白不与字符串一起打印,而是与其后的下一个打印行一起打印

    我尝试打印一行 要求用户输入 获取输入 然后再次打印一些行 问题是 在我获得输入后 第一个打印行末尾的空白不是打印在该行的末尾 而是打印在第二个打印行的开头 我对 C 完全陌生 所以我不能真正尝试太多 但我尝试在没有提示用户输入的部分的情况
  • 如何像用户打字一样将输入发送到控制台?

    这是我的问题 我有一个程序必须在 TTY 中运行 cygwin 提供了这个 TTY 当我重定向 stdIn 时 程序失败 因为它没有 TTY 我无法修改该程序 并且需要某种方法使其自动化 如何抓取 cmd exe 窗口并向其发送数据并使其认
  • 如何将 model.summary() 保存到 Keras 中的文件?

    有model summary 方法 https keras io models about keras models 在喀拉斯 它将表打印到标准输出 是否可以将其保存到文件中 如果您想要摘要的格式 您可以传递print功能为model su
  • 从 stdin 读取后,PHP 在每行上给出尾随“=”

    stdin 的内容因自动换行和尾随 而被损坏 这显然破坏了我需要发布的 URL 我需要从电子邮件中提取 URL 链接 然后发布该 URL 因此 我使用我在互联网上看到的标准代码片段将电子邮件传输到 cpanel 中的 php 脚本 fd f
  • 在Python中通过sys.stdout写入unicode字符串

    暂时假设一个人无法使用print 从而享受自动编码检测的好处 所以这给我们留下了sys stdout 然而 sys stdout太蠢了不做任何合理的编码 http bugs python org issue4947 现在人们阅读 Pytho
  • TCL 脚本 - exec 将文本刷新到我的标准输出

    我怎样才能 冲洗 stdout of the exec命令到我的脚本stdout没有 等待 结果执行返回 例如在下面的脚本中我想要git clone输出立即出现在我的脚本上下文中 usr bin tclsh git outputs prog
  • Perl:测试输入阅读器?

    有没有一种方法可以使用标准 Test 等模块自动测试 Perl 程序是否正在读取输入 例如标准输入正确吗 例如 测试一个从 STDIN 读取两个整数并打印它们之和的程序 这不是 100 清楚你的意思 我会回答假设你想编写一个测试脚本来测试你
  • 如何将 emscripten 浏览器输入法从 window.prompt 更改为更合理的输入法?

    我有一个 C 函数 一旦调用它就会消耗来自 stdin 的输入 使用 emscripten 将此函数导出到 javascript 会导致调用 window prompt 与浏览器提示交互确实是一项乏味的任务 首先 您一次只能粘贴一行 其次
  • 将 iPhone 上的 stderr 写入文件和控制台

    我正在遵循答案中的建议here https stackoverflow com questions 5179108 iphone how to read application logs from device用于将 iOS 设备上的 NS
  • C 将标准输出恢复到终端

    我正在使用多线程程序 首先 我将标准输出重定向到某个文件 没问题 我用过dup2 fd 1 where fd是文件的文件描述符 之后 我需要再次将标准输出重定向到终端 我的第一个方法 Declaration fpost t stream s
  • 将 stdin/stdout 从执行进程重定向到 Perl 中的管道

    我试图让执行子进程中的 STDOUT STDERR 通过 Perl 中的管道返回到父进程 我见过的最接近我想做的事情是 http forums devshed com perl programming 6 exec and redirect
  • 在 Linux 上,在 Eclipse CDT 中使用 gdb 调试 C++ 应用程序,如何向 stdin 输入内容?

    在 Linux 上 我尝试在 Eclipse CDT 中使用 gdb 调试 C 应用程序 例如应用程序applic exe接受一些命令行参数arg1 and arg2它期望一些数据stdin 比如说 取自文件input txt 通常 要在控
  • 捕获并邮寄 bash 脚本错误

    我有一个脚本 每晚在 cron 中运行 为网络上的多个主机备份一些 postgres 数据库 我有一种方法可以通过利用退出状态来收到脚本失败的警报 但它没有告诉我失败的原因 根据以下代码 我如何捕获脚本运行时发生的任何错误 并将其通过电子邮
  • 让 python 脚本打印到终端而不作为标准输出的一部分返回

    我正在尝试编写一个返回值的 python 脚本 然后我可以将其传递给 bash 脚本 问题是我想要在 bash 中返回一个单一值 但我想要一些东西一路打印到终端 这是一个示例脚本 我们称之为 return5 py usr bin env p
  • Bash:替换管道标准输入中的子字符串

    我尝试用新的子字符串替换标准输入中的某个子字符串 在读取几个文件后 我必须从管道获取标准输入cat 然后我想将更改后的字符串向前推到管道中 这是我尝试做的 cat file1 file2 echo cat path to file path

随机推荐

  • python项目打包发布详解

    PyInstaller打包Python项目详解 lt h1 gt lt div class 61 34 clear 34 gt lt div gt lt div class 61 34 postBody 34 gt PyInstaller打
  • python批处理打开多个文件

    背景 xff1a 有时候我们需要在服务器上同时运行多个程式 xff0c 但是却需要一个一个的打开 xff0c 比较费时间 xff0c 而且一旦服务器重启后 xff0c 不懂程式运行的人受限于环境及代码原理 xff0c 很难逐个将程式逐个打开
  • 挂载别的系统挂掉的磁盘解决步骤,mount: unknown filesystem type ‘LVM2_member‘ 报错

    挂载别的系统挂掉的磁盘解决步骤 1 在新的虚机添加磁盘 按照下边操作步骤即可使linux系统重新读取并识别到新硬盘 xff1a 1 1 确定主机总线号 xff1a root 64 iNeedle ls sys class scsi host
  • 序设计思维与实践 CSP-M4

    A 题意 xff1a 题目描述 这一天 xff0c TT因为疫情在家憋得难受 xff0c 在云吸猫一小时后 xff0c TT决定去附近自家的山头游玩 TT来到一个小湖边 xff0c 看到了许多在湖边嬉戏的鸭子 xff0c TT顿生羡慕 此时
  • C++ 构造函数详解

    目录 0 什么是构造函数 1 默认构造函数 2 一般构造函数 3 拷贝构造函数 4 转换构造函数 5 移动构造函数 0 什么是构造函数 在定义类的成员函数的时候 xff0c 一般的成员函数与普通的全局函数没有太大的区别 xff0c 在定义函
  • Copilot 简单测评

    年初的时候通过了Copilot的试用申请资格 xff0c 试用到现在也几个月了 xff0c 说一下使用的感受 最开始理解Copilot xff0c 是通过注释来生成代码 xff0c 在这个想法下 xff0c 感觉自己又又又又要失业了 xff
  • iPhone开发【十四】多线程开发之NSThread——子线程模拟耗时操作

    转载请注明出处 xff0c 原文网址 xff1a http blog csdn net m changgong article details 8213964 作者 xff1a 张燕广 实现的功能 xff1a 1 xff09 演示多线程开发
  • 学习c语言的总结

    学习时间 xff1a 早上9点 晚上9点 学习内容 xff1a 利用c语言对 的代码学习 xff0c 并根据自己的理解编写代码 xff0c 最后整合学习的代码和自己理解的代码 xff0c 编写出更优的代码 学习体会 xff1a 对一个问题举
  • Makefile使用细节

    变量及通配符 A 61 C 即时变量 xff0c 此时C未定义 xff0c A为空 B 61 C 延时变量 xff0c 用到B时再确定具体的值 C 61 abc C 61 123 C不是第一次定义 xff0c 被忽略 C 43 61 789
  • Debian修改桌面系统

    今天 xff0c 装了Debian xff0c 发现其桌面不好看 xff0c 感觉就像瘟逗死系统 xff0c 寻思着更换一下 xff0c 于是就度娘 xff0c 但遗憾的是没有找到 xff0c 想一下不如自个儿研究哈哈 xff0c 所以记录
  • csp 序列查询新解 解决70分超时和错误的思路

    这个题的代码我再也不会看的 因为这题就是一个发现数与数之间联系的一道题 xff0c 不会再看了 总结一下 xff1a 这道题别人AC是用了两层for循环 但内层的for里第三个条件不是i 43 43 是i 43 61 一个区间长度 这就过了
  • bat批处理文件建立和打开

    一 新建bat文件 1 1新建文本文件 xff0c 在文本文件写入如下内容 xff1a xff08 注意不要有中文路径和中文名称 xff09 格式 xff1a start 目录路径 app exe 具体的实例如下所示 xff1a start
  • 安装树莓派vnc或者xrdp出错解决办法(树莓派ping不同Windows、但是Windows可以ping通树莓派)(树莓派上搭建好了vnc环境和xrdp环境)

    1 1出现问题 博主按照这篇教程https blog csdn net naibozhuan3744 article details 84961041搭建树莓派vnc环境或者xrdp环境时 xff0c 一直出现win10系统ping不通树莓
  • C++可变参数模板函数基本用法

    可变参数模板可以创建任意个参数的模板函数和模板类 xff0c 本文主要介绍可变参数模板函数 1 1可变参数模板函数声明和定义 template lt typename Args gt Args是一个模板参数包 void Show Args
  • python+KLT光流法匹配

    span class token comment 光立法匹配 span span class token function import span numpy as np span class token function import s
  • python3 最长公共前缀

    给定一个大小为 n 的字符串数组 strs xff0c 其中包含n个字符串 编写一个函数来查找字符串数组中的最长公共前缀 xff0c 返回这个公共前缀 import random import re class Solution def l
  • Android Studio 设置阿里云镜像代理(如果设置之后还是远程仓库下载失败,请仔细阅读其内容就可以解决了)

    1 在project的build gradle文件的repositories标签和allprojects标签的repositories标签下加入以下阿里云镜像代理 xff08 如下图一和图二 xff0c 记得要把阿里云镜像代理放在repos
  • scnprintf()和snprintf()、vscnprintf()和vsnprintf()

    写过Linux驱动或者内核态程序的人应该都知道 xff0c 编译时会有这样一个警告 xff1a use scnprintf instead of snprintf 为什么在编译驱动或者内核态程序的时候会有这个警告呢 xff1f 据说因为sn
  • CentOS 8.5安装-解决Error setting up base repository问题

    CentOS 8 5安装 解决Error setting up base repository CentOS 8简介 1 CentOS 8 版本介绍CentOS 8 的新特性CentOS 8所需硬件配置 CentOS 8 5安装CentOS
  • stdout, stdin, stderr的区别

    stdin stdout stderr的中文名字分别是标准输入 xff0c 标准输出和标准错误 当一个用户进程被创建的时候 xff0c 系统会自动为该进程创建三个数据流 xff0c 一个程序要运行 xff0c 需要有输入 输出 xff0c