美文网首页
关于Python调用系统命令:os.system

关于Python调用系统命令:os.system

作者: 龙star180 | 来源:发表于2022-05-22 14:21 被阅读0次

            昨天跟一学生讨论这个Python调用系统命令,想以前笔者都是用的最简单的os.system(command),结果昨天学生说因为os.system是创建了一个子进程。不会影响主进程(他的理解就是这个子进程创建了,下面的语句不会等os.system结束就会继续执行,所以他以前总是出一些找不到os.system调用的命令生成的文件等报错。),所以他后来一直用的os.popen()——笔者也知道他参考的是哪篇博客:https://blog.csdn.net/yu97271486/article/details/104878616?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1-104878616-blog-88383312.pc_relevant_scanpaymentv1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-1-104878616-blog-88383312.pc_relevant_scanpaymentv1&utm_relevant_index=1。说真的,他这么一说,笔者还真不确定了——确实以前没有去想过这种情况,一直认为是按照Python等编程的顺序原则执行,也没想过子进程和主进程的事。

            因此,有必要去实践一下,到底他理解的对,还是我理解的对。经过2个多小时的思考和查阅资料和实践。结论:我曾经想当然的是对的。他的那些问题是因为他对路径理解不清晰导致的。

            首先,官方或很多优秀的博客(https://blog.csdn.net/bcfdsagbfcisbg/article/details/78180650?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-78180650-blog-103495195.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-78180650-blog-103495195.pc_relevant_default&utm_relevant_index=1)都明确指定,os.system本身就是阻塞的(图1)。正确的应该怎么理解,就是这个子进程不结束(不管是正确执行也好,遇到错误几位数也好),后面的语句不会执行(管你是主进程Python的语句,还是后面又调用了其他的命令(子进程):不管是shell命令还是各种Linux软件程序命令)。反倒是os.popen本身是不阻塞的,所以会出现学生理解的情况(他参考的博客对os.popen的解释是正确的),所以要通过read()或readlines()对命令结果进行读,才能产生阻塞的效果(如图2)。

    图1 图2

            经过各种资料、逻辑和自己测试的整合,笔者现在确定os.system是一个最简单,能满足我们需求的好方法(图3)。

    图3

    关于学生参考博客的一个纠正(图4):

    图4

            不是因为他理解的,os.system('cd /usr/local')在子进程了,所以下面的os.mkdir('aaa.txt')没等子进程结束就执行了。所以:误人子弟

            其实,因为os.system()本身是阻塞的,正如前面分析的,所以就是顺序执行的,os.system()不执行完,下面的os.mkdir('aaa.txt')不执行。产生博主描述的效果的原因如图4中的红色所解释。

            因此,只要把os.mkdir('aaa.txt')修改为os.mkdir('/usr/local/aaa.txt')就是博主需要的效果了。

            而且,博客所给出的解决方案,说要用;把多条需要先后执行的命令写在一行,保证在同一子进程。笔者也看了一些网上的其他博客(https://blog.csdn.net/keepaware/article/details/116609705和https://blog.csdn.net/u011119817/article/details/119744799),确实也这么建议的。这里,笔者赞同这种思想。但是笔者自己测试,其实写成两个os.system(),效果也是一样的——因为是阻塞的,依旧遵循编程的顺序原则。所以,笔者这里大胆认为:网上这些博客给的写在一个子进程的出发点和思想是对的,好的,而且确实能节省代码行数并且似乎更保险。但是只要理解了阻塞,其实能达到自己的需求(图3红框内容、图6)。

            如图5,截图中的前两行注释语句就是遵从保证在一个子进程中执行的写法。笔者的意思就是其实也可以写成图5非注释的语句内容,但根据前面的分析,cd ./bin/是多余的,并没有满足我的需求——因为要调用bpRepeatScan还是要指定路径才行。(实际上,笔者这个非注释行会报错File opening failed: No such file or directory,这个笔者猜测就是学生所遇到的情况了。因为bpRepeatScan要在bin目录下用./bpRepeatScan才能正确被识别和调用(就算在bin目录下执行,不用./会报错:-bash: bpRepeatScan: command not found)——这个./在Linux中就是保证子进程与主进程能正常传递变量)

    图5

            所以合并一下为cd ./bin/; ./bpRepeatScan,如图6:

    图6

            与图6前两行注释代码的效果一样,区别为图6为两个子进程,两行注释代码为一个子进程。

            总结完毕,祝自己越来越好!

    相关文章

      网友评论

          本文标题:关于Python调用系统命令:os.system

          本文链接:https://www.haomeiwen.com/subject/mtykprtx.html