• Linux python运维


    Python 是一种高级编程语言,它具有简单易学、可移植性强、丰富的第三方库等特点,因此成为了广泛应用于各个领域的编程语言之一。而在 Linux 系统中,Python 的使用也十分普遍。本文将介绍如何在 Linux 系统中执行 Python 脚本并传入参数,以及如何在 Python 中获取这些参数。

    1. 在 Linux 中执行 Python 脚本

    在 Linux 系统中执行 Python 脚本非常简单,只需在终端中输入以下命令:

    1. `bash
    2. python script.py
    3. “`

    其中,script.py 是你要执行的 Python 脚本的文件名。如果 Python 脚本位于当前目录下,则可以省略路径,直接输入文件名即可。

    2. 在 Linux 中给 Python 脚本传入参数

    如果你要给 Python 脚本传入参数,则可以在执行 Python 脚本的命令中添加参数。例如:
     

    1. “`bash
    2. python script.py arg1 arg2
    3. “`

    上述命令中,arg1 和 arg2 就是传入的参数。在 Python 脚本中,可以使用 sys 模块获取这些参数。具体操作如下:

    1. “`python
    2. import sys
    3. if __name__ == ‘__mn__’:
    4. args = sys.argv[1:]
    5. print(args)
    6. “`

    上述代码中,sys.argv 是一个列表,其中之一个元素是 Python 脚本的文件名,而从第二个元素开始,便是传入的参数。因此,我们可以使用 sys.argv[1:] 将传入的参数提取出来,并打印出来。

    3. 在 Python 中获取参数

    上述方法虽然可以获取参数,但是获取到的参数都是以字符串的形式呈现,如果需要将参数转换为其他的数据类型,则需要进行特殊的处理。下面是几个示例:

    比如:将参数转换为整数型

    1. “`python
    2. import sys
    3. if __name__ == ‘__mn__’:
    4. arg1 = int(sys.argv[1])
    5. arg2 = int(sys.argv[2])
    6. print(arg1 + arg2)
    7. “`

    4、Python脚本在Linux上怎么运行

     有两种方式:

    1、直接使用python xxxx.py执行。其中python可以写成python的绝对路径。使用which python进行查询。

    2、在文件的头部写上#!/usr/bin/python2.7,这个地方使用python的绝对路径,就是上面用which python查询来的结果。然后在外面就可以使用./xxx.py执行了。

    因为在linux中,python是普通的文本格式,都需要一种程序取解释执行它。要么调用的时候指定,要么在文件头指定。

    5、Python调用Shell命令

    用Python调用Shell命令有如下几种方式:

    1. os.system

    os.system("The command you want").
    os.system("lscpu").
    os.system("ls -al").

    这个调用相当直接,且是同步进行的,程序需要阻塞并等待返回。返回值是依赖于系统的,直接返回系统的调用返回值,所以windows和linux是不一样的。

    2. os.popen

    os.popen(command[,mode[,bufsize]])

    可以看出,popen方法通过p.read()获取终端输出,而且popen需要关闭close().当执行成功时,close()不返回任何值,失败时,close()返回系统返回值. 可见它获取返回值的方式和os.system不同。

    3. subprocess《Python文档中目前全力推荐》

    subprocess使用起来同样简单:

    直接调用命令,返回值即是系统返回。shell=True表示命令最终在shell中运行。Python文档中出于安全考虑,不建议使用shell=True。

    二、使用步骤

    python源码示例:

    1. # -*- coding:utf-8 -*-
    2. import os, subprocess, time
    3. #该文件测试python嗲用shell的四种方法
    4. current_workspace = os.path.join(os.path.dirname(os.path.abspath(__file__)))
    5. workspace='/mnt/e/00.WORKSPACE/00.Python_Develop/ToolsLibrarByPython'
    6. '''
    7. os.system() 调用的C库
    8. def system(command: StrOrBytesPath) -> int: ... 返回整数,返回0则表示执行成功
    9. # os.system(str) 方法:
    10. # 1.可以执行linux命令,可以加参数
    11. # 2.可以执行shell脚本,也可以加参数
    12. # 3.特别的,重定向可以直接通过linux重定向进行,
    13. # 但是这样重定向输出局限于当前linux执行的服务器,无法重定向到当前程序执行的目录
    14. '''
    15. def excute_shell_by_os_system():
    16. # cmd -> str
    17. status = os.system('ls')
    18. print(status)
    19. #cmd命令,+参数(python str 语法加参数)
    20. status = os.system('find %s -name "*.py"|sort' %workspace) #python str 占位符号
    21. print(status)
    22. status = os.system('find {} -type f'.format(workspace)) #python str.format()
    23. print(status)
    24. status = os.system(f"find {workspace} -type f") #python str f表达式
    25. print(status)
    26. #cmd 执行shell脚本
    27. status = os.system('./shell_demo.sh')
    28. print(status)
    29. #cmd 执行带有参数的shell脚本
    30. status = os.system('./shell_demo_with_param.sh %s' %workspace)
    31. print(status)
    32. #cmd 执行shell脚本, 重定向到某个文件
    33. status = os.system('./shell_demo.sh > %s' %(os.path.join(current_workspace, 'log.txt')))
    34. print(status)
    35. #cmd 执行shell脚本, 终端输出同时写入
    36. status = os.system('./shell_demo.sh|tee %s' %(os.path.join(current_workspace, 'log1.txt')))
    37. print(status)
    38. '''
    39. os.popen(cmd)
    40. return os._wrap_close'>:返回值是连接管道的文件对象
    41. 该方法返回linux命令执行的结果
    42. read()方法返回,linux执行命令输出;
    43. readline()方法返回第一行;
    44. readlines()方法返回:
    45. ['total 28\n', '-rwxrwxrwx 1 root root 9000 Oct 19 23:04 log.txt\n',]
    46. '''
    47. def excute_shell_by_os_popen():
    48. return_content = os.popen('ls -l')
    49. #print(type(return_content.read())) #<class 'str'> 注意:每次读取之后,就会释放,第二次就读取不到
    50. print(return_content.read())
    51. return_content = os.popen('ls -l')
    52. print(return_content.readline())
    53. print('-------------------------------------')
    54. return_content = os.popen('ls -l')
    55. print(return_content.readlines())
    56. return_content = os.popen('./shell_demo.sh')
    57. print(return_content.readline())
    58. return_content = os.popen('./shell_demo.sh', 'r')
    59. print(type(return_content))
    60. return_content = os.popen('find {} -type f'.format(workspace))
    61. print(return_content.readline())
    62. '''
    63. python 3已经用subprocess代替commands模块
    64. Deprecated since version 2.6: The commands module has been removed in Python 3.
    65. Use the subprocess module instead.'''
    66. def excute_shell_by_commands():
    67. pass
    68. '''
    69. return subprocess.CompletedProcess'>
    70. '''
    71. def excute_shell_by_subprocess():
    72. result = subprocess.run('ls -l', shell=True)#默认打印linux执行结果
    73. print("-------------------------------------")
    74. print(result) #CompletedProcess(args='ls -l', returncode=0)
    75. print(result.args) #ls -l
    76. print(result.returncode) #0 表示执行成功
    77. print(result.stdout) #默认传入None
    78. print(result.stderr)#默认传入None
    79. '''
    80. 文件重定向
    81. '''
    82. #使用linux自带的重定向输出将打印结果保存到文件中
    83. result = subprocess.run('ls -l > %s'%(os.path.join(current_workspace, 'stdout_o.log')), shell=True)#保存到文件
    84. result = subprocess.run('ls -l |tee %s'%(os.path.join(current_workspace, 'stdout_o.log')), shell=True)#打印并保存到文件
    85. if result.returncode != 0:
    86. print("excute '%s' failed!" % result.args)
    87. else:
    88. print("excute '%s' successful!!" % result.args)
    89. #将终端打印的信息保存到文件中【输出内容和错误信息分别保存到对应的文件】
    90. #stderr file对象
    91. #stdout file对象
    92. with open(os.path.join(current_workspace, 'stdout.log'), 'w') as f_o:
    93. with open(os.path.join(current_workspace, 'stderr.log'), 'w') as f_e:
    94. result = subprocess.run('ls -l', shell=True, stderr=f_e, stdout=f_o)
    95. if result.returncode != 0:
    96. print("excute '%s' failed!" % result.args)
    97. else:
    98. print("excute '%s' successful!!" % result.args)
    99. print("--------------------------------------*****---------------------------------------------")
    100. result1 = subprocess.run(['find', workspace,'-type','f'], shell=False) #特别注意这个位置 shell设置为False,否则不生效
    101. print(result1)
    102. result = subprocess.run('ls -l', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)# 返回变量
    103. print(result)#return tuple(stdout, stderr)///tuple(bytes, bytes)
    104. def excute_shell_by_subprocess_Popen():
    105. #Popen
    106. print("--------------------------------------**&&**---------------------------------------------")
    107. # 实例化Popen对象,打印执行结果,但是进程未结束,一直处于等待中...
    108. # result = subprocess.Popen(['ls', '-l'])# 若没指定stdout和stderr,会打印结果, communicate会返回None
    109. result = subprocess.Popen(['ls', '-l'], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)# return <class 'subprocess.Popen'>
    110. #简单说communicate() 和wait()的区别,使用 subprocess 模块的 Popen 调用外部程序,
    111. #如果 stdout 或 stderr 参数是 pipe,并且程序输出超过操作系统的 pipe size时,
    112. #如果使用 Popen.wait() 方式等待程序结束获取返回值,会导致死锁,程序卡在 wait() 调用上
    113. #那死锁问题如何避免呢?官方文档里推荐使用 Popen.communicate()。这个方法会把输出放在内存,
    114. #而不是管道里,所以这时候上限就和内存大小有关了,一般不会有问题。而且如果要获得程序返回值,
    115. #可以在调用 Popen.communicate() 之后取 Popen.returncode 的值。
    116. # Attributes:【stdin, stdout, stderr, pid, returncode】
    117. print("-------------------------------@@@@@@@@-----------------------------------------------")
    118. print(result.stdin)
    119. print(result.stdout.read()) #<_io.BufferedReader name=3>
    120. print(result.stderr.read()) #return error
    121. print(result.pid) # return pid:224
    122. print(result.returncode) # return int
    123. print("-------------------------------@@@@@@@@-----------------------------------------------")
    124. #function:【communicate(), wait(), terminate(), poll()】
    125. result_communicate = result.communicate()# return <class 'tuple'>
    126. print(result_communicate)# return (bytes, bytes)
    127. ## 设置等待时间,终止进程
    128. time.sleep(5) #设置一个等待时间,确保结果被打印
    129. result.terminate() #终止进程
    130. #该方法可以代替如上语句
    131. result_wait = result.wait(time.sleep(2)) #等待 time.sleep(10)进程结束,在结束当前linux进程
    132. print(result_wait) # return int
    133. print(result.poll()) #return int; 检查当前进程是够结束,若结束则返回 0
    134. # """Check if child process has terminated. Set and return returncode attribute."""
    135. #subprocess another api
    136. def excute_shell_by_subprocess_old_api():
    137. result = subprocess.call(['ls', '-l']) #return <class 'int'>, 0 success; 同时打印结果
    138. print(result)# return 0
    139. print("-------------------------------------------------------------------------------------")
    140. result = subprocess.check_call(['ls', '-l'])#return <class 'int'>, 0 success; 同时打印结果, same call()
    141. print(result)
    142. print("-------------------------------------------------------------------------------------")
    143. result = subprocess.check_output(['ls', '-l'])#return <class 'bytes'>; 返回查询结果bytes
    144. print(result)
    145. print("-------------------------------------------------------------------------------------")
    146. result = subprocess.getoutput(['ls', '-l'])#return <class 'str'>; 返回查询结果 str
    147. ##特别注意:当前返回结果,不包含 total:36(linux中显示当前所有文件的大小总和)
    148. print(result)
    149. print("-------------------------------------------------------------------------------------")
    150. result = subprocess.getstatusoutput(['ls', '-l'])#return <class 'tuple'>/(status, output) tuple
    151. print(result)#status:int ; output: str
    152. if __name__ == '__main__':
    153. # demo
    154. excute_shell_by_os_system()
    155. excute_shell_by_os_popen()
    156. excute_shell_by_subprocess()
    157. excute_shell_by_subprocess_old_api()
    158. excute_shell_by_subprocess_Popen()

    几个关键注意点:

    输入
    字符串形式:cmd通过字符串格式输入,os、subprocess皆支持;特别注意参数传入,按照python的字符串要求传入即可(%s,str.format(),python3 f表达式)。
    命令以列表形式传入:当前只有subprocess模块支持
    执行linux结果
    打印执行结果 :os模块默认打印;subprocess.Popen()实例不指定stdout,stderr时候。
    返回执行结果状态 :os.system();subprocess.run(cmd).returncode,subprocess.call(cmd),subprocess.check_call(cmd),subprocess.getstatusoutput()[0]
    返回执行结果,可以将结果赋值给变量 :os.popen().raeds();subprocess.Popen(cmd,stdout=subprocess.PIPE, stderr=subprocess.PIPE).run(),subprocess.check_output(),subprocess.getoutput(),subprocess.getstatusoutput()[1]
    将执行结果打印到文件中:两种思路,一种是通过linux本身自带的重定向写入文件,另一种是使用subprocess指定stdout为本地文件即可
    两个模块的对比:
    返回结果:
    os.system(cmd),打印结果,返回执行结果状态(0执行成功);
    os.popen(cmd),打印结果,同时返回执行结果(一个打开的文件对象);
    subprocess模块可以根据实际需求返回对应的结果。
    使用场景:
    os模块,常常用于简单的linux命令操作
    subprocess模块,长用于shell等大型交付场景使用(个人建议直接使用该模块)
     

    参考:

    1、https://www.dbs724.com/340499.html

    2、python3调用linux/shell—【标准库:os模块&subprocess模块】_subprocess.run_半斗烟草的博客-CSDN博客 

  • 相关阅读:
    PAT 1029 Median
    Java—Double类型进行加减乘除出错(精度)问题
    ElasticSearch教程(详解版)
    如何基于Github Pages + Hexo 的方式,免费搭建个人博客?
    子网的划分
    杀掉redis进程 并启动redis
    巨神奇,2013年的老Mac,竟直接装上macOS Ventura 13.1 Beta版
    Prometheus远程存储方案
    SpringBoot线程上下文传递数据
    网络安全1
  • 原文地址:https://blog.csdn.net/qq_35789269/article/details/133758970