当前位置: 首页 > news >正文

Lab2_Simple Shell_2020

Lab2: 实验目的:给xv6添加新的系统调用

并理解系统调用是如何工作的,并理解xv6内核的一些内部特征

实验准备:

  1. 阅读xv6的第2章以及第4章的4.3,4.3小节
  2. 熟悉下面的源码
  • 用户态相关的代码:user/user.huser/usys.pl
  • 内核态相关的代码:kernel/syscall.hkernel/syscall.h
  • 进程相关的代码:kernel/proc.kernel/proc.c

​ 3. 阅读KR大佬C语言书的如下章节

 2.9 (Bitwise operators) and 5.1 (Pointers and addresses) through 5.6 (Pointer arrays) and 6.4 (pointers to structures) by Kernighan and Ritchie (K&R)

任务1:系统调用跟踪功能 System call tracing (moderate)

In this assignment you will add a system call tracing feature that may help you when debugging later labs. You’ll create a new trace system call that will control tracing. It should take one argument, an integer “mask”, whose bits specify which system calls to trace. For example, to trace the fork system call, a program calls trace(1 << SYS_fork), where SYS_fork is a syscall number from kernel/syscall.h. You have to modify the xv6 kernel to print out a line when each system call is about to return, if the system call’s number is set in the mask. The line should contain the process id, the name of the system call and the return value; you don’t need to print the system call arguments. The trace system call should enable tracing for the process that calls it and any children that it subsequently forks, but should not affect other processes.

在本作业中,你需要添加一个系统调用跟踪功能,该功能可能会在以后调试实验室时对您有所帮助。您将创建一个新的“trace”系统调用来控制跟踪。它应该有一个参数,一个int 类型的“mask”,其bits位说明要跟踪的系统调用。例如,为了跟踪fork系统调用,程序调用trace(1 << SYS_fork),其中SYS_fork是来自kernel/syscall.h的系统调用号。如果在mask中设置了系统调用的编号,则必须修改xv6内核,以便在每个系统调用即将返回时打印出一行数据。该行应包含进程id、系统调用的名称和返回值;不需要打印系统调用参数。trace这个系统调用函数应启用对调用它的进程及其随后fork的任何子进程的跟踪,但不应影响其他进程。

我们提供了一个用户态的trace程序,它运行另一个启用了跟踪的程序(参见user/trace.c)。完成后,您应该看到如下输出:

$ trace 32 grep hello README
3: syscall read -> 1023
3: syscall read -> 966
3: syscall read -> 70
3: syscall read -> 0
$
$ trace 2147483647 grep hello README
4: syscall trace -> 0
4: syscall exec -> 3
4: syscall open -> 3
4: syscall read -> 1023
4: syscall read -> 966
4: syscall read -> 70
4: syscall read -> 0
4: syscall close -> 0
$
$ grep hello README
$
$ trace 2 usertests forkforkfork
usertests starting
test forkforkfork: 407: syscall fork -> 408
408: syscall fork -> 409
409: syscall fork -> 410
410: syscall fork -> 411
409: syscall fork -> 412
410: syscall fork -> 413
409: syscall fork -> 414
411: syscall fork -> 415
...
$ 

在上面的第一个例子中,trace调用grep tracing,而仅仅是read系统调用。32是1<<SYS_read(1<<5 = 2^5=32)的结果。在第二个例子中,trace在跟踪所有系统调用时运行grep;2147583647具有全部31个低位(2^31 = 2147583647)。在第三个示例中,程序没有被跟踪,因此没有打印跟踪输出。在第四个示例中,跟踪usertests(forkforkfork)程序中所有的fork系统调用(包含所有的子进程)。如果你的程序的输出如上所示,则解决方案是正确的(尽管进程ID可能不同)。

我们需要增加一个trace的系统调用,trace 接受一个int型参数,用来设置具体哪些系统调用函数需要跟踪到;

例如 trace 32意思SYS_read 函数需要被跟踪,32是1<<SYS_read(1<<5 = 2^5=32)的结果 ;

具体修改如下所示:

  • Add $U/_trace to UPROGS in Makefile

  • 运行make qemu,你将看到编译器无法编译user/trace.c,因为系统调用的用户空间存根还不存在:将系统调用的原型添加到user/user.h,将存根添加到user/usys.pl,以及对应的syscall编号添加到kernel/syscall.h。Makefile会先调用perl脚本user/usys.pl,它生成user/usys.S,即实际的系统调用存根,它使用RISC-v的ecall指令转换到内核。一旦你修复了编译问题,运行trace32 grep hello README;它将失败,因为您尚未在内核中实现系统调用。

    image-20210514153148919

    image-20210514153233553

    image-20210514153328513

  • kernel/sysproc.c中添加一个sys_trace() 函数,通过在proc结构体的新增加一个变量,我们这里用的是char mask[23]中记住其参数来实现新的系统调用(kernel/proc.h)。这个函数需要从用户空间检索系统调用的参数kernel/syscall.c中,你可以在kernel/sysproc.c中看到它们的使用示例。

    // kernel/sysproc.c 增加下面函数
    uint64
    sys_trace(void)
    {int n;// 获取n之后,如果小于0,也返回-1if(argint(0, &n) < 0 && n < 0)return -1;// 通过n控制哪些系统调用函数需要被trace // n=32是`1<<SYS_read(1<<5 = 2^5=32)`的结果 // 反推的话,n>>1...22; 每次判断n是奇数还是偶数,可以判断当前位是多少// 这里可以用n&1=0 偶数 n&1=1 奇数 来判断奇数偶数struct proc *p=  myproc();char *mask =p->mask;for(int i = 0; i < 23; i++)// syscall num 从0开始{if(n&1)mask[i]='1';elsemask[i]='0';n>>=1;}return 0;
    }

    image-20210514153512603

  • 修改fork()(参见kernel/proc.c)将trace mask参数从父进程复制到子进程。

    image-20210514153708281

  • 修改kernel/syscall.c中的syscall()函数以打印跟踪输出。你需要添加一个syscall名称数组来进行索引。

  // kernel/syscall.cvoidsyscall(void){int num;struct proc *p = myproc();num = p->trapframe->a7;if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {p->trapframe->a0 = syscalls[num]();if('1' == p->mask[num]) // p->mask 只有trace的时候才会修改它,见kernel/sysproc.c->sys_traceprintf("%d: syscall %s -> %d\n", p->pid, syscallnames[num], p->trapframe->a0);} else {printf("%d %s: unknown sys call %d\n",p->pid, p->name, num);p->trapframe->a0 = -1;}}

总结 遇到的一点小坑:

  1. "%d: syscall %s -> %d\n这里冒号后面需要加上空格,第一次没加上空格,死活匹配不过去,发现后被自己气死;

  2. trace children案例有超时时间,31s的时候就time out了,鉴于我ubuntu14,还是虚拟机,碍于性能问题总是跑超时,其实答案是对的,修改gradelib.py, 增加了判题的超时时间,就过去了;

    image-20210514155522566

贴下这道题的完结图:

image-20210514155627914

$ export PATH=$PATH:/home/moocos/riscv-gnu-toolchain/bin/bin //路径可以替换为你自己的路径
//然后编译xv6
$ make
$ make qemu
...
mkfs/mkfs fs.img README user/_cat user/_echo user/_forktest user/_grep user/_init user/_kill user/_ln user/_ls user/_mkdir user/_rm user/_sh user/_stressfs user/_usertests user/_wc user/_zombie user/_cow 
nmeta 46 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 1) blocks 954 total 1000
balloc: first 497 blocks have been allocated
balloc: write bitmap block at sector 45
qemu-system-riscv64 -machine virt -kernel kernel/kernel -m 3G -smp 3 -nographic -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
hart 0 starting
hart 2 starting
hart 1 starting

Sysinfo (moderate)

In this assignment you will add a system call, sysinfo, that collects information about the running system. The system call takes one argument: a pointer to a struct sysinfo (see kernel/sysinfo.h). The kernel should fill out the fields of this struct: the freemem field should be set to the number of bytes of free memory, and the nproc field should be set to the number of processes whose state is not UNUSED. We provide a test program sysinfotest; you pass this assignment if it prints “sysinfotest: OK”.
在本作业中,您将添加一个系统调用sysinfo,用于收集有关正在运行的系统的信息。系统调用有一个参数:一个指向struct sysinfo的指针 (参见kernel/sysinfo.h)。内核应填写此结构的字段:freemem字段应设置为可用内存的字节数,nproc 字段应设置为状态 不是UNUSED的进程数。我们提供了一个测试程序sysinfotest;如果它输出“sysinfotest:OK”,则通过此作业。

一些提示:

  • 按照上次添加systrace的步骤,添加sysinfo
  • 收集空闲内存量,需要在kernel/kalloc.c中添加一个函数,这个函数来获取一个全局变量,标识内存量
  • 收集进程数,需要在kernel/proc.c中添加一个函数,这个函数来获取一个全局变量,标识进程数
  • 然后内核函数sysinfo(info)读取上面两个变量,然后将struct sysinfo 的值从内核空间拷贝到用户空间(copyout),完成调用

具体修改点如下

  • makefile增加_sysinfotest编译项:

    image-20230219114421145

  • user/usys.pl增加sysinfo的入口

    image-20230219114503105

  • user/user.h 增加sysinfo结构体和函数声明

image-20230219114533254

  • 创建user/sysinfo.c ,进入xv6可以执行,sysinfo查看系统内存,相当于新增一个shell函数

    image-20230219114752738

  • kernel/sysproc.c 增加头文件及sysinfo的函数实现,这里是内核态的实现,需要通过argaddr获取用户态调用的传参,并把内核态的数据通过copyout拷贝给用户态

    image-20230219114950679

image-20230219114938723

  • kernel/proc.c 返回系统的进程数量,推荐作法新增函数直接遍历获取。

    image-20230219120340958

  • kernel/kalloc.c 增加函数返回内存使用量

image-20230219120746946

  • kernel/def.h里增加函数声明

    image-20230219120829236

  • kernel/syscall.h 增加系统调用号

image-20230219115754429

  • kernel/syscall.c 增加syscalls和syscallnames的定义

image-20230219115902993

image-20230219120012942

补充trace的修改

  • kernel/proc.h 增加MASKSIZE=24的定义

image-20230219120049248

  • kernel/sysproc.c 同样补充遍历条件

    image-20230219115643648

最后执行结果

image-20230219121359818

一点点反思

侵入式修改_反例

不好的做法,反例:定义一个全局变量,申请的时候++,释放的时候–,侵入式修改,修改了原有代码,后续需求变化还会引起散弹式修改,不好不好

  • kernel/proc.c 返回系统的进程数量

image-20230219120230974

image-20230219120306096

image-20230219120313248

  • 返回系统可用内存

image-20230219120536056

image-20230219120548284

相关文章:

Lab2_Simple Shell_2020

Lab2: 实验目的&#xff1a;给xv6添加新的系统调用 并理解系统调用是如何工作的&#xff0c;并理解xv6内核的一些内部特征 实验准备&#xff1a; 阅读xv6的第2章以及第4章的4.3,4.3小节熟悉下面的源码 用户态相关的代码&#xff1a;user/user.h和user/usys.pl内核态相关的代…...

2023最全电商API接口 高并发请求 实时数据 支持定制 电商数据 买家卖家数据

电商日常运营很容易理解&#xff0c;就是店铺商品维护&#xff0c;上下架&#xff0c;评价维护&#xff0c;库存数量&#xff0c;协助美工完成制作详情页。店铺DSR&#xff0c;好评率&#xff0c;提升客服服务等等&#xff0c;这些基础而且每天都必须做循环做的工作。借助电商A…...

MySQL 的索引类型

1. 按照功能划分 按照功能来划分&#xff0c;索引主要有四种&#xff1a; 普通索引唯一性索引主键索引全文索引 普通索引就是最最基础的索引&#xff0c;这种索引没有任何的约束作用&#xff0c;它存在的主要意义就是提高查询效率。 普通索引创建方式如下&#xff1a; CREATE…...

< Linux > 进程信号

目录 1、信号入门 生活角度的信号 技术应用角度的信号 前台进程 && 后台进程 信号概念 用kill -l命令察看系统定义的信号列表 信号处理的方式 2、信号产生前 用户层产生信号的方式 3、产生信号 3.1、通过终端按键产生信号 3.2、核心转储core dump 3.3、调用系统函数…...

Pyspark基础入门7_RDD的内核调度

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…...

C/C++每日一练(20230307)

目录 1. 国名排序 ★★ 2. 重复的DNA序列 ★★★ 3. 买卖股票的最佳时机 III ★★★ &#x1f31f; 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 ​专栏 1. 国名排序 小李在准备明天的广交会&#xff0c;明天有来自世界各国的客房跟他们谈生意&#xff0c…...

一条SQL查询语句是如何执行的?

平时我们使用数据库&#xff0c;看到的通常都是一个整体。比如&#xff0c;你有个最简单的表&#xff0c;表里只有一个ID字段&#xff0c;在执行下面这个查询语句时&#xff1a; mysql> select * from T where ID10&#xff1b; 我们看到的只是输入一条语句&#xff0c;返…...

tcsh常用配置

查看当前的shell类型 在 Linux 的世界中&#xff0c;有着许多 shell 程序。常见的有&#xff1a; Bourne shell (sh) C shell (csh) TC shell (tcsh) Korn shell (ksh) Bourne Again shell (bash) 其中&#xff0c;最常用的就是bash和tcsh&#xff0c;本次文章介绍tcsh的…...

YOLOv5源码逐行超详细注释与解读(2)——推理部分detect.py

前言 前面简单介绍了YOLOv5的项目目录结构&#xff08;直通车&#xff1a;YOLOv5源码逐行超详细注释与解读&#xff08;1&#xff09;——项目目录结构解析&#xff09;&#xff0c;对项目整体有了大致了解。 今天要学习的是detect.py。通常这个文件是用来预测一张图片或者一…...

什么叫个非对称加密?中间人攻击?数字签名?

非对称加密也称为公钥密码。就是用公钥来进行加密&#xff0c;撒子意思&#xff1f; 非对称加密 在对称加密中&#xff0c;我们只需要一个密钥&#xff0c;通信双方同时持有。而非对称加密需要4个密钥&#xff0c;来完成完整的双方通信。通信双方各自准备一对公钥和私钥。其中…...

2023.03.07 小记与展望

碎碎念系列全新改版&#xff01; 以后就叫小记和展望系列 最近事情比较多&#xff0c;写篇博客梳理一下自己3月到5月下旬的一个规划 一、关于毕设 毕设马上开题答辩了&#xff0c;准备再重新修改一下开题报告&#xff0c;梳理各阶段目标。 毕设是在去年的大学生创新训练项目…...

MyBatis源码分析(七)MyBatis与Spring的整合原理与源码分析

文章目录写在前面一、SqlSessionFactoryBean配置SqlSessionFactory1、初识SqlSessionFactoryBean2、实现ApplicationListener3、实现InitializingBean接口4、实现FactoryBean接口5、构建SqlSessionFactory二、SqlSessionTemplate1、初始SqlSessionTemplate2、SqlSessionTemplat…...

基于声网 Flutter SDK 实现多人视频通话

前言 本文是由声网社区的开发者“小猿”撰写的Flutter基础教程系列中的第一篇。本文除了讲述实现多人视频通话的过程&#xff0c;还有一些 Flutter 开发方面的知识点。该系列将基于声网 Fluttter SDK 实现视频通话、互动直播&#xff0c;并尝试虚拟背景等更多功能的实现。 如果…...

IT服务管理(ITSM) 中的大数据

当我们谈论IT服务管理&#xff08;ITSM&#xff09;领域的大数据时&#xff0c;我们谈论的是关于两件不同的事情&#xff1a; IT 为业务提供的大数据工具/服务 - 对业务运营数据进行数字处理。IT 运营中的大数据 – 处理和利用复杂的 IT 运营数据。 面向业务运营的大数据服务…...

Validator校验之ValidatorUtils

注意&#xff1a;hibernate-validator 与 持久层框架 hibernate 没有什么关系&#xff0c;hibernate-validator 是 hibernate 组织下的一个开源项目 。 hibernate-validator 是 JSR 380&#xff08;Bean Validation 2.0&#xff09;、JSR 303&#xff08;Bean Validation 1.0&…...

C++---背包模型---采药(每日一道算法2023.3.7)

注意事项&#xff1a; 本题是"动态规划—01背包"的扩展题&#xff0c;dp和优化思路不多赘述。 题目&#xff1a; 辰辰是个天资聪颖的孩子&#xff0c;他的梦想是成为世界上最伟大的医师。 为此&#xff0c;他想拜附近最有威望的医师为师。 医师为了判断他的资质&…...

Java各种锁

目录 一、读写锁(ReentrantReadWriteLock) 二、非公平锁(synchronized/ReentrantLock) 三、可重入锁/递归锁(synchronized/ReentrantLock) 四、自旋锁(spinlock) 五、乐观锁/悲观锁 六、死锁 1、死锁代码 2、死锁的检测(jps -l 与 jstack 进程号) 七、sychronized-wait…...

TryHackMe-Tardigrade(应急响应)

Tardigrade 您能否在此 Linux 端点中找到所有基本的持久性机制&#xff1f; 服务器已遭到入侵&#xff0c;安全团队已决定隔离计算机&#xff0c;直到对其进行彻底清理。事件响应团队的初步检查显示&#xff0c;有五个不同的后门。你的工作是在发出信号以使服务器恢复生产之前…...

导出GIS | 将EXCEL表格中坐标导出成GIS格式文件

一 前言 EXCEL是我们日常工作学习数据处理的办公软件&#xff0c;操作易上手&#xff0c;几乎人人都会用。EXCEL表格能够处理各种数据&#xff0c;包括经纬度坐标数据&#xff0c;地址数据等等。 有时因工作需要需将表格中地址数据处理为GIS格式的文件&#xff0c;以便能够将数…...

new set数组对象去重失败

我们知道Set是JS的一个种新的数据结构&#xff0c;和数组类似&#xff0c;和数组不同的是它可以去重&#xff0c;比如存入两个1或两个"123"&#xff0c;只有1条数据会存入成功&#xff0c;但有个特殊情况&#xff0c;如果添加到set的值是引用类型&#xff0c;比如数组…...

Acwing: 一道关于线段树的好题(有助于全面理解线段树)

题目链接&#x1f517;&#xff1a;2643. 序列操作 - AcWing题库 前驱知识&#xff1a;需要理解线段树的结构和程序基本框架、以及懒标记的操作。 题目描述 题目分析 对区间在线进行修改和查询&#xff0c;一般就是用线段树来解决&#xff0c;观察到题目一共有五个操作&…...

DD-1/40 10-40mA型【接地继电器】

系列型号&#xff1a; DD-1/40接地继电器 DD-1/50接地继电器 DD-1/60接地继电器 一、 用途及工作原理 DD-1型接地继电器为瞬时动作的过电流继电器&#xff0c;用作小电流接地电力系统高电压三相交流发电机和电动机的接地零序过电流保护。继电器线圈接零序电流互感器(电缆式、母…...

【女神节】简单使用C/C++和Python嵌套for循环生成一个小爱心

目录 前言实现分析代码实现代码如下效果如下优化效果代码如下效果如下总结尾叙前言 女神节马上到了,有女朋友的小伙伴是不是已经精心准好礼物了呢!对于已婚男士,是不是整愁今天又该送什么礼物呢!说真的,我也整愁着,有什么要推荐么,评论留言下! 实现分析 可以先在纸上或…...

Biome-BGC生态系统模型与Python融合技术实践应用

查看原文>>> Biome-BGC生态系统模型与Python融合技术实践应用 Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。 在Biome-BGC模型中&#xf…...

ESP32 GPIO使用

ESP32 GPIO使用 #define GPIO_OUT_PIN 2 //定义引脚号 #define GPIO_OUTPUT_PIN_SEL (1<<GPIO_OUT_PIN) //定义输出引脚的宏&#xff0c;用来将输出引脚号转换为位掩码void bsp_gpio_init(){gpio_config_t io_conf;io_conf.pin_bit_mask GPIO_OUTPUT_PIN_SE…...

JavaScript 高级4 :正则表达式

JavaScript 高级4 &#xff1a;正则表达式 Date: January 19, 2023 Text: 正则表达式、正则表达式特殊字符、正则表达式中的替换 目标&#xff1a; 能够说出正则表达式的作用 能够写出简单的正则表达式 能够使用正则表达式对表单进行验证 能够使用正则表达式替换内容 正则…...

如何让AI帮你干活-娱乐(3)

背景今天的话题会偏代码技巧一些&#xff0c;对于以前没有接触过代码的朋友或者接触代码开发经验较少的朋友会有些吃力。上篇文章介绍了如何广视角的生成相对稳定的视频。昨天的实现相对简单&#xff0c;主要用的是UI界面来做生成。但是生成的效果其实也显而易见&#xff0c;不…...

webview的工作、内存泄漏、漏洞以及缓存机制原理原理+方案解决

分析一段appium的日志来分析webview的工作原理&#xff0c;文章尾部附有自动化脚本及完整日志&#xff1a; 解析&#xff1a; 获取上下文列表 服务端发送命令adb shell cat /proc/net/unix获取域套接字列表。那什么是域套接字呢&#xff1f; 域套接字&#xff1a;是unix系统里…...

BFD协议原理

BFD协议原理引入背景不使用BFD带来的问题OSPF感知慢VRRP产生次优路径BFD技术简介BFD会话建立方式和检测机制BFD会话建立过程BFD工作流程BFD的单臂回声BFD默认参数以及调整方法总结引入背景 随着网络应用的广泛部署&#xff0c;网络发生中断可能影响业务正常运行并造成重大损失…...

你把骑行当什么? 它就是你需要的

1.骑行是一种有活力的运动&#xff0c;尝试一下你一定会喜欢上它的&#xff01;2.把骑行当作一种娱乐&#xff0c;让自己快乐地体验自然的美&#xff01;3.骑行可以帮助你改变心态&#xff0c;让你的心情变得更加愉悦&#xff01;4.让骑行成为你每天的计划&#xff0c;看看骑行…...

西安网站优化排名/餐饮营销策划方案

UVM中的类和常用组件UVM中的类uvm_objectuvm_componentUVM中的常见组件driversequencermonitoragentenvironmentreference model & scoreboardUVM中的类 UVM中所有的类都有一个共同的基类&#xff1a;uvm_void 类。它没有数据成员&#xff0c;也没有成员函数。由uvm_void …...

用jsp做留言板网站/百度搜索大全

版权声明&#xff1a; 本账号发布文章均来自公众号&#xff0c;承香墨影&#xff08;cxmyDev&#xff09;&#xff0c;版权归承香墨影所有。 未经允许&#xff0c;不得转载。 一、前言 在 Android 系统中&#xff0c;当运行的 App 被移动到后台的之后&#xff0c;Android 为了保…...

如何做网站的下载的二维码/谷歌搜索引擎

查看thinkphp版本号方法php打开文件“根目录\ThinkPHP\ThinkPHP.php”下的文件ThinkPHP.php&#xff0c;在22--23行能够看到版本信息THINK_VERSION,以下图&#xff1a;css说明&#xff1a;此方法不破坏原有的Thinkphp框架&#xff0c;对之后框架升级没影响&#xff0c;而且能够…...

我想做卖鱼苗网站怎样做/网站站长seo推广

说明&#xff1a; &#xff08;1&#xff09;如何查看容器内有多少个对象&#xff1f; 前面介绍了如何在容器内创建对象和设置对象之间的关系&#xff1b;但是&#xff0c;所有这些信息&#xff0c;都是我们自动脑补去想象的&#xff1b;如果一个项目足够大&#xff0c;对象很多…...

深圳专业商城网站制作/seo推广经验

Android 图表开源框架之MPAndroidChart PieChart扇形图&#xff08;一&#xff09; Android 图表开源框架之MPAndroidChart PieChart扇形图&#xff0c;版本&#xff1a;3.0.1 implementation com.github.PhilJay:MPAndroidChart:v3.0.1 效果图1&#xff1a; 效果图2&#x…...

做网站就/seo点击软件

这里主要总结下&#xff0c;在 Python 代码脚本里&#xff0c;涉及到调用 Shell 脚本、终端命令行、其它 Python 脚本的场景. 1. 方法1 - os.system() os.system() - 只返回状态码&#xff0c;执行结果会输出到stdout&#xff0c;即输出到终端. 仅在 Linux 中有效. 用法&#x…...