在程序里面执行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中,那么,这样会影响程序的执行效率么? 通过示 ...
随机推荐
- Linux增加系统调用(亲测成功)
我使用的操作系统是CentOS,其他的操作系统类似. 相关软件和Linux的基础操作这里不再赘述. 实验环境 VMWare Workstation.CentOS-7 实验步骤 ...
- Linux开机启动三种方式
有的时候,我们开机启动一些命令或者是一段脚本,又或者是开机启动自定义的服务. 下面归纳了2种实现的方式. 方式1-开机启动命令 vim /etc/rc.local #添加你想执行的命令 chmod + ...
- C语言:if(0)之后的语句真的不会执行吗?
C语言--if(0)之后的语句真的不会执行吗? 原文(有删改):https://www.cnblogs.com/CodeWorkerLiMing/p/14726960.html 前言 学过c语言的都知 ...
- 全国产!全志A40i+Logos FPGA核心板(4核ARM Cortex-A7)硬件说明
硬件资源 SOM-TLA40iF核心板板载ARM.FPGA.ROM.RAM.晶振.电源.LED等硬件资源,并通过B2B连接方式引出IO.核心板所有器件(包括B2B连接器)均采用国产工业级方案,国产化率 ...
- (Java)日志框架体系整理
# JUL 指的是Java Util Logging包,它是Java原生的日志框架,使用时不需要另外引用第三方的类库,相对其他的框架使用方便,学习简单,主要是使用在小型应用中.@紫邪情 # JUL的组 ...
- Vue2 整理(三):高级篇
前言 基础篇链接:https://www.cnblogs.com/xiegongzi/p/15782921.html 组件化开发篇链接:https://www.cnblogs.com/xiegongz ...
- 转-查看Linux CPU个数,核心,线程数
CPU 个数 grep 'physical id' /proc/cpuinfo | sort -u CPU 核心数 grep 'core id' /proc/cpuinfo | sort -u | w ...
- 如何让 3D 数字孪生场景闪闪发光
今日图扑软件功能分享:我们将探讨 HT 系统如何通过分组管理灯光.裁切体和流光,以提高场景光影效果的精准度和整体可控性. HT 中的灯光.裁切体.流光是会影响它所在区域一定范围内的其他节点的表现,如 ...
- vue项目坑记录:vue项目运行卡在百分之几几几
今天晚上打着游戏,同事突然叫我拉项目下来运行,我打完就去拉代码了,结果vue项目运行卡在66%不动了,我也是百度一下分享别人怎么解决的文章给他,继续我的游戏! 结果呢? 游戏结束后,我拉代码,还是这个 ...
- exp解析
1 #pragma once 2 #include <string> 3 #include <functional> 4 #include <type_traits> ...