详解Python命令行参数

Last Updated: 2024-05-13 01:40:47 Monday

-- TOC --

Python本身是一个用户态程序,有自己的命令行参数,用$python -h显示所有命令行参数及其help信息。

-V

查看Python版本,大V!

-m

-m mod : run library module as a script (terminates option list)

其实就是以__name__ == __main__这样的方式运行某个模块。

$ python3 -m http.server
$ python3 -m tkinter
$ python3 -m timeit ...
$ python3 -m unittest ...

注意一个细节,此时命令行不再需要写文件后缀.py,直接写模块名称即可(.py文件就是一个Python模块)。

学点英语:terminates option list,终结选项列表。

很多第三方package,即是library,也是命令行工具,通过-m参数运行。

-i

-i : inspect interactively after running script; forces a prompt even if stdin does not appear to be a terminal; also PYTHONINSPECT=x

此参数的功能是,在运行完python代码后,直接进入interactive模式。在有 -i 参数的情况下,python解释器先执行代码,然后不退出解释器,而是直接进入交互模式。此时,我们在交互模式下,就可以查看各种对象的状态,并可以在交互模式下调用调试。

-c

-c cmd : program passed in as string (terminates option list)

python解释器的 -c 选项,表示将后面的输入作为cmd来执行。cmd其实就是python的语句(statement)。所以,这就是在命令行直接执行python代码!

$ python3 -c "import sys; print(sys.executable)"
/usr/bin/python3
$ python3 -c "
> import random
> for i in range(10):
>   print(random.randint(0,9))
> "
5
5
2
2
5
5
7
4
9
2

上面的测试代码,有两个细节:

  1. 不能写成这样: $ python3 -c "import random; for i in .....",这样代码在python解释器中也是语法错误,分号(;)的使用不适合这样的for;
  2. for 语句后的那一行,缩进只有两个空格,代码能够正确执行;这与在exec函数中输入的代码字符串一样。(4个空格的缩进不再是强制的,只要有缩进并对齐,python解释器就能够正确识别)

bash -c相似。

-q

-q : don't print version and copyright messages on interactive startup

安静地进入Python交互模式。

-u

-u : force the stdout and stderr streams to be unbuffered;

取消向stdout的输出缓存。

有时在python3 xxxx.py | grep 'yyy'的时候,不能及时看到过滤出来的输出行,就是因为这个原因。加上-u就好了!(或者调用print的时候,设置flush=True

关于管道的执行细节

假设有:

$ a | b
  1. 并不是左边的a命令执行完毕后,再执行右边的b命令,左右两个命令的进程几乎是同时都起来的;
  2. 左边a命令的输出,通过管道给右边b命令,这个过程可能有缓存,因此可能会产生两个进程的执行是从左到右顺序的错觉;

基于这些理解,尝试写个简陋的tee.py,配合python的-u参数测试,如果不使用-u参数,屏幕上的显示就会有明显的延时,并且很不自然:

$ python3 -u ~/repos/pingscan/pingscan.py 192.168.16.0/24 | python3 tee.py
Pingscan network 192.168.16.0/24 with 64 workers (mt_ping):
192.168.16.1       4/4
192.168.16.104     4/4
Hosts: 2/254
$ cat test.txt
Pingscan network 192.168.16.0/24 with 64 workers (mt_ping):
192.168.16.1       4/4
192.168.16.104     4/4
Hosts: 2/254
$ cat tee.py
import sys

if not sys.stdin.isatty():
    with open('test.txt', 'w') as f:
        while line:=sys.stdin.readline():
            f.write(line)
            print(line, end='')

-O

-O: remove assert and debug-dependent statements; add .opt-1 before .pyc extension; also PYTHONOPTIMIZE=x

移除所有assert语句。所以,在代码中使用assert是没有问题的!

-OO

-OO: do -O changes and also discard docstrings; add .opt-2 before .pyc extension

进一步移除docstrings。

-和sys.argv

通过sys.argv查看命令行参数list:

$ python3 -q - a b c d e
>>> import sys
>>> sys.argv
['-', 'a', 'b', 'c', 'd', 'e']
>>> 

如果此处不使用-,python就会认为a是一个脚本文件去尝试打开。其实-的含义是从stdin来获取输入:

$ echo 'import sys; print(len(sys.argv))' | python3 -
1
$ echo 'import sys; print(len(sys.argv))' | python3 - a b c d e
6
$ cat test_python_dash.py 
print('test python dash')
$ python3 - < test_python_dash.py 
test python dash

当stdin没有任何输入的时候,Python进入interactive模式。

sys.argv里面的参数排列,与其它系统或语言的参数排列类似,0号参数对应的都是脚本名称(如果是一个脚本的话)。

很多时候,直接使用sys.argv来获取命令行的参数,比使用argparse模块要方便。

-X utf8

启动Python UTF8模式,具体参考此文

本文链接:https://cs.pynote.net/sf/python/202202055/

-- EOF --

-- MORE --