command-line, argv, ci,

命令行参数的传参与使用

DolorHunter DolorHunter Follow Jul 11, 2021 · 12 mins read

命令行参数的传参与使用
Share this

在使用非图形界面或者某些进阶操作时,总是无可避免的会用到命令行。其中的一些命令行带有参数,可以以不同的状态运行程序。

比如 v2ray/v2fly 的下载命令长这样:

$ bash <(curl -L -s https://install.direct/go.sh)

其中的 -L-s 就是参数。 -L 表示 location,如果服务器报告请求页面有不同位置将重新获取位置;-s 表示 slient,不显示进度表和错误信息。

程序通过获取不同的执行的参数,以执行不同的代码。这部分的内容其实跟函数传参差不多,只是可能因为没怎么用到,在学习过程中通常都会忽略。main函数中的argc,argv[]就是用来做参数传递的。

int main( int argc, char *argv[] )

这次也是借着给 项目PR 才比较完整的窥见命令行参数的传参与使用。之前自己做的命令行项目通常只有一种运行模式,图形界面有模式的区别但也是在子函数去做功能,因此还并没有遇到这个问题。这次是在修改别人的代码,原本是在桌面端执行的程序,我加入一个在GitHub Action上执行的选项,来完成定时爬虫的任务。

为了原本保证代码的兼容,在一番魔改之后又改了回去,仅仅加入了一个用于判断是否是gh Action的变量用来跳出原先桌面端的 while True 循环。虽然看着这个while True很不顺眼,但是觉得如果改动的话,在桌面端挂机还要设置定时任务,相比原来可能会比较麻烦就又改了回去。gh Action部分没什么好说的,设置了三个trigger:push触发、五分钟定时触发、手动触发,功能性代码仅仅写了一行 python main.py

但是这样也会引发一些问题,如果用户 fork 了仓库,却因为不使用 bark 只想在本地运行,但是gh action的定时任务爬虫就会定时运行,就相当于action在空跑。还有一个比较小的问题就是区分桌面端运行还是action运行,我是在 main.py 内设置了一个需要手动修改的全局变量,而 tangyisheng2 则帮我修改成命令行参数,在main内自动检测参数,让我大开眼界。

Python 的命令行参数只有 argv,并且需要使用 sys 库。使用的方法很简单,用 len 可以计算参数数量,用 argv 获得所有参数,用 argv[] 按位置取参数。

import sys

print("Number of argument:", len(sys.argv))
print("First argument:", sys.argv[0])
print("Argument List:", sys.argv)

测试结果:

$ python .\0712.py -a -b -c -d
Number of arguments: 5
First argument: .\0712.py
Argument List: ['.\\0712.py', '-a', '-b', '-c', '-d']

利用以上的命令行传参与使用功能,用于判断是否是在 action 环境下运行,需要手动修改的全局变量,就变成在 main 中检测自动修改了。

GitHub Action 脚本加入了action参数:

python main.py --action

main.py 加入了命令行代码的传参与使用:

if len(sys.argv) > 1 and sys.argv[1] == "--action":
  enable_gh_action = True  # 检测是否在GitHub Action中运行

这样就不用手动修改 action 参数了,也避免在使用上因为忘记修改某些参数而发生的奇怪问题。比如说,如果在 action 上的定时任务还用 while True 一直跑,那还得了?

参考资料:

Join Newsletter
Get the latest news right in your inbox. We never spam!
DolorHunter
Written by DolorHunter
Developer & Independenet Blogger