python 实现命令行工具 tee
最近,朋友 Litreily 发表了文章Linux指令 - tee的实现 ,是用 C 语言实现的 tee 命令,那我凑个热闹用 python 实现一下下!
tee命令
macOS下也有 tee 命令,好像跟 linux 下的有一点点差别,这个小节讲一下 macOS 下的 tee 命令的使用,总该感受下它的功能才能实现它吧!
tee的功能
打开终端,输入命令 man tee
可以查看 tee 的手册,介绍非常简单,当然是因为这个命令功能很简单。
TEE(1) BSD General Commands Manual TEE(1)
NAME
tee -- pipe fitting
SYNOPSIS
tee [-ai] [file ...]
DESCRIPTION
The tee utility copies standard input to standard output, making a copy in zero or more files. The output is unbuffered.
The following options are available:
-a Append the output to the files rather than overwriting them.
-i Ignore the SIGINT signal.
The following operands are available:
file A pathname of an output file.
The tee utility takes the default action for all signals, except in the event of the -i option.
The tee utility exits 0 on success, and >0 if an error occurs.
STANDARDS
The tee function is expected to be POSIX IEEE Std 1003.2 (``POSIX.2'') compatible.
BSD June 6, 1993 BSD
功能简单来说就是把标准输入传输给标准输出(打印出来)的同时将输入内容写入到指定文件,而在指定文件的时候加上 -a
会在文件内容的基础上追加输入而不是覆盖^[tee 命令]。
tee的使用
还是得实际使用使用才能感受它的功能:
$ tee log.txt
test
test
原来如此
原来如此
^C
$ cat log.txt
test
原来如此
$ tee -a log.txt
生活如此多彩
生活如此多彩
^C
$ cat log.txt
test
原来如此
生活如此多彩
$ tee
hah
hah
^C
- tee 命令指定文件
log.txt
,输入内容敲回车就会打印输入的内容,比如test
和原来如此
,CTRL + c 退出命令,用 cat 命令查看log.txt
的内容与输入的内容一致。 - 加入
-a
选项,就会在指定文件追加输入的内容,比如生活如此精彩
。 - 不指定文件的话,只会打印输入的内容。
python实现tee
这里只实现上面 tee的使用 小节中测试的功能。
文件准备
-
新建文件:
touch tee
-
为文件添加运行权限:
chmod +x tee
-
文件中指明解释器,添加以下内容到
tee
文件中:#!/usr/bin/env python3
-
文件中导入必要的库:
import sys import argparse
- sys 库用于操作标准输入输出;
- argparse 库用于解析命令参数,这个库的基本使用可以参考我的另一篇文章 argparse 库的使用
解析命令参数
这里将使用 argparse 库解析参数的操作封装为函数 getargs
:
def getargs():
"""获取命令参数
"""
parser = argparse.ArgumentParser(description="The tee utility copies standard \
input to standard output, making a \
copy in zero or more files. The \
output is unbuffered.")
parser.add_argument('-v', '--version', action='version', version="v 1.0.0")
parser.add_argument('-a', '--append', action="store_true", default=False, help='Append the output to the files rather than overwriting them.')
parser.add_argument('file', nargs='*', help='A pathname of an output file.')
return parser.parse_args()
tee功能实现
直接在 __main__
中实现 tee 的功能如下:
if __name__ == '__main__':
args = getargs()
filemode = 'a' if args.append else 'w'
while True:
line = sys.stdin.readline()
sys.stdout.write(line)
for file in args.file:
with open(file, filemode) as f:
f.write(line)
if filemode is 'w':
filemode = 'a'
可以看到代码非常简单就实现了 tee 的完整功能,直接操作 sys.stdin
、sys.stdout
^[使用python实现tee的效果] 和 文件^[实现tee命令]即可!最终代码可参考:tools-with-script/tee/tee。
测试
$ ./tee --help
usage: tee [-h] [-v] [-a] [file [file ...]]
The tee utility copies standard input to standard output, making a copy in
zero or more files. The output is unbuffered.
positional arguments:
file A pathname of an output file.
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-a, --append Append the output to the files rather than overwriting them.
$ ./tee
12
12
$ ./tee log.txt
where
where
who i am
who i am
$ cat log.txt
where
who i am
$ ./tee -a log.txt
that's good
that's good
$ cat log.txt
where
who i am
that's good
$ ./tee -a log.txt log1.txt
Wonderful
Wonderful
$ cat log.txt
where
who i am
that's good
Wonderful
$ cat log1.txt
Wonderful
测试步骤解释如下:
- 打印帮助信息;
- 不指定任何参数,只会将标准输入打印到标准输出;
- 指定文件
log.txt
,标准输入分别输入where
和who i am
,标准输出也分别打印了; - 查看
log.txt
内容与上一步的标准输入一致; - 指定文件
log.txt
并指定为追加模式,标准输入that's good
,标准输出正常显示that's good
; - 查看
log.txt
内容是在原来的内容上追加了上一步输入的that's good
; - 指定两个文件
log.txt
和log1.txt
,并指定为追加模式,标准输入Wonderful
,标准输出正常打印; - 查看
log.txt
内容是在原来的内容上追加了上一步输入的that's good
,而新文件log1.txt
内容为上一步的Wonderful
;