在程序里面执行system(“cd /某个目录“),为什么路径切换不成功?
粉丝提问:
彭老师,问下,在程序里面执行system("cd /某个目录"),这样会切换不成功,为啥呢

实例代码:

粉丝的疑惑是明明第10行执行了cd /media操作,
为什么12行执行的pwd > test2.txt
结果提示的仍然是当前目录?
这是一个很不错的问题,要想整明白这个问题,需要知道system的原理。
system()函数
通过man手册来查看system库函数: 
由手册可得:
- system()是库函数
- 通过fork()函数创建子进程
- 在子进程中通过exec族函数执行shell命令
这样大家就明白了,实际上system执行参数中的字符串代表的命令,
其实是创建了一个进程,然后在子进程中通过exec族函数来执行对应的命令。
当前工作路径,cwd,可以通过pwd来获取,
那么工作路径是和进程相关的,
第10行代码执行之后,虽然确实改变了此时的子进程的工作路径,
但是随着子进程的退出该工作路径已没有意义,
而执行到12行程序的时候,system()又会创建新的子进程,
该子进程仍然继承父进程的工作路径,
所以当前工作路径就没有变化。
程序中如何修改当前程序的工作路径?
可以通过函数chdir()
CHDIR(2) Linux Programmer's Manual CHDIR(2)
NAME
chdir, fchdir - change working directory
SYNOPSIS
#include <unistd.h>
int chdir(const char *path);
int fchdir(int fd);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
fchdir():
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
DESCRIPTION
chdir() changes the current working directory of the calling process to the directory specified in path.
fchdir() is identical to chdir(); the only difference is that the directory is given as an open file descriptor.
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
该函数是个系统调用(system是库函数)。
代码举例:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 int main(int argc, char **argv)
6 {
7 system("ls");
8 chdir("/");
9 system("ls");
10 return 0;
11 }
peng@ubuntu:~/test$ ./run
123.c a.sh basic chat chris encryption net run sgm3141 srand
app boot dev home initrd.img.old lib32 libx32 media opt root sbin srv tftpboot usr vmlinuz www
bin cdrom etc initrd.img lib lib64 lost+found mnt proc run snap sys tmp var vmlinuz.old
由结果可知,8行代码修改了当前进程的工作路径为根路径,
所以第9行执行ls命令显示的是根路径下面的内容
验证system()
下面我们来看一下,system()这个函数是如何调用系统调用的。
编写测试函数
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(int argc, char **argv)
5 {
6 system("ls");
7 return 0;
8 }
要想知道某个函数调用过程,最终调用到哪些系统调用函数,可以借助strace命令
在Linux系统中,strace命令是一个集诊断、调试、统计与一体的工具,可用来追踪调试程序,能够与其他命令搭配使用
执行结果:

由截图可知,
当我们运行程序时,首先会加载链接库,以便于我们执行当前程序,
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
最终调用到系统调用函数clone(),
clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x7fffdff4b59c) = 2753
并获取到执行结果
wait4(2753, 123.c a.sh basic chat chris encryption net run sgm3141 srand
但是前面说了,system不是调用fork的吗?
man clone

写的很清楚了,clone与fork行为一致。
好了,本文就到这,想学linux的老铁,抓紧加一口君好友吧!
在程序里面执行system(“cd /某个目录“),为什么路径切换不成功?的更多相关文章
- 使用System.Timers.Timer类实现程序定时执行
使用System.Timers.Timer类实现程序定时执行 在C#里关于定时器类有3个:System.Windows.Forms.Timer类.System.Threading.Timer类和Sys ...
- 如何用程序删除win 7下SYSTEM权限的目录
win7系统由于安装程序等操作,可能会在系统中留下一些所有权限是SYSTEM角色的目录,例如我的系统以前在C盘的QQ卸载后的遗留文件(下图). System是Windows系统中最高权限角色(组),比 ...
- Android开发第一讲之目录结构和程序的执行流程
1.如何在eclipse当中,修改字体 下面的这种办法,可以更改xml的字体 窗口--首选项--常规--外观--颜色和字体--基本--文本字体--编辑Window --> Preferences ...
- 在c++程序中执行DOS命令
转自博客:http://blog.csdn.net/ypist/article/details/8485049 #1,system()方式 在C盘根目录下新建文件夹,名称为12: system(&qu ...
- CLR via C# 摘要一:托管程序的执行模型
托管程序的执行模型大致如下: 编译源代码为程序集(dll或exe文件),程序集包括了记录相关信息的元数据和IL代码 执行程序集文件时,启动CLR,JIT负责把IL编译为本地代码并执行 IL是微软推出的 ...
- Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
- [转帖]浅析java程序的执行过程
浅析java程序的执行过程 转帖来源: https://www.cnblogs.com/wangjiming/p/10315983.html 之前学习过 这一块东西 但是感觉理解的不深刻. copy一 ...
- 在Web应用程序中执行计划任务(多线程)
在业务复杂的应用程序中,有时候会要求一个或者多个任务在一定的时间或者一定的时间间隔内计划进行,比如定时备份或同步数据库,定时发送电子邮件等,我们称之为计划任务.实现计划任务的方法也有很多,可以采用SQ ...
- 003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程
003 01 Android 零基础入门 01 Java基础语法 01 Java初识 03 Java程序的执行流程 Java程序长啥样? 首先编写一个Java程序 记事本编写程序 打开记事本 1.wi ...
- 多余的Using Namespaces或引用会影响程序的执行效率么?
在.NET程序编写中,需要using相应命名空间或添加相应的References,可有时候没有使用到的命名空间也被添加到了Using Namespaces中,那么,这样会影响程序的执行效率么? 通过示 ...
随机推荐
- WPS中导入endnote插件
WPS中导入endnote插件 1. 找到 Endnote 插件的目录: D:\Program Files (x86)\EndNote 20\Product-Support\CWYW 2. 把Cw ...
- DotNetGuide专栏C#/.NET/.NET Core充电站(让你学习不迷路)
DotNetGuide简介 记录.收集和总结C#/.NET/.NET Core基础知识.学习路线.开发实战.编程技巧练习.学习视频.文章.书籍.项目框架.社区组织.开发必备工具.常见面试题.面试须知. ...
- 「转」Android编译选项中的eng、user、user-debug
Android编译选项中eng.user.user-debug主要区别 reference: https://blog.csdn.net/dearsq/article/details/52589376 ...
- 分享两个内置Google广告位的Typecho主题
前言 很多项目的开始都是因为情怀和热爱,"为爱发电"是一件很值得尊敬的事情,然而大量"为爱发电"的项目最后却不得不因"难以为继"而被迫停服. ...
- SpringMVC原理(1)-文件上传请求
我们文件上传接口只需要在方法参数上写MultipartFile类,mvc就可以帮我们把上传的文件封装为这个类的对 象供我们非常方便的操作,那它是怎么做的呢?我们一起来看看 我们发的请求默认都是由Dis ...
- 全国产T3+FPGA的SPI与I2C通信方案分享
近年来,随着中国新基建.中国制造2025规划的持续推进,单ARM处理器越来越难胜任工业现场的功能要求,特别是如今能源电力.工业控制.智慧医疗等行业,往往更需要ARM + FPGA架构的处理器平台来实现 ...
- 使用64位Office2016处理万级数据的过程
先放下载和安装教程https://mp.weixin.qq.com/s/5ym9950_NZROlN0s2ZmLTg 由于同事电脑在使用Mysql for Excel插件处理十万级数据,如下图: 爆出 ...
- ST 表整体二分解法
整体二分时遍历数组从 \(mid\) 开始的最大值再合并就可以了,时间 \(O(n \log n + q)\) 空间 \(O(n)\). #include<bits/stdc++.h> / ...
- CF620E
题目 CF620E 思路 这个题是一个在树上操作的题,每次操作的对象都是以一个结点为根的子树,在1e5的操作下暴力做法必然会超时 观察到c的范围很小,可以考虑状态压缩 考虑将此问题转化为区间问题,利用 ...
- Unity的Package库在IDE里不显示API注释的解决方法
当你在代码里使用Package库的API的时候,比如Addressable和Unity.Entities等等,以Visual Studio为例,鼠标放到API上,会发现不显示注释: 然而按F12访问源 ...