Linux下进程的特点与环境变量

目录

进程的特点

进程特点的介绍

进程时如何实现并发性的

进程间如何切换

概念铺设

PC指针

上下文

环境变量

PATH

修改PATH

HOME

SHELL

env

命令行参数

什么是命令行参数?

打印命令行参数

通过函数获得环境变量

getenv

命令行参数 env

修改环境变量

环境变量总结

本地变量 & 内建命令

查看本地变量

内建命令


进程的特点

根据我们前面学习过的进程,我们总结一下进程的特点。

  • 竞争性:进程直接是相互竞争的,进程想要运行就必须竞争CPU资源,也需要竞争其他资源。

  • 独立性:进程之间是互不干扰的,所以如果某一个进程挂掉之后并不会影响其他的进程。

  • 并行性:如果在多CPU的环境下,多个进程可以同时运行。

  • 并发性:在单CPU的环境下,进程之间是基于时间片轮转的,进程在运行特定的时间后就必须换下一个进程来运行。

进程特点的介绍

竞争性:由于我们每一个进程想要运行都是需要占用CPU资源的,但是我们的CPU只有一个,所以我们的进程必须竞争CPU资源,所以我们的进程是具有竞争性的。

独立性:在前面学习的子进程中,我们的父子进程共享同一份代码,而数据也是写时拷贝的,并且我们的进程都是有自己独立的代码和数据,所以我们进程也是互补干扰的,所以为我们的进程时具有独立性的。

并行性:当计算机有多个CPU的时候,计算机内多个进程就可以在多个CPU上同时运行,所以这就是进程的并行性。

并发性:由于大多数环境下计算机中都只有一个CPU,所以为了让进程都可以得到CPU资源,那么就需要让进程可以在运行的时候切换,让每个进程执行特定的时间就切换到下一个进程,由于计算机的速度时很快的,所以我们并不会感受到进程间切换的卡顿感。

下面我们主要介绍一下进程的并发性。

进程时如何实现并发性的

在计算机中一定有很多的进程,所以进程之间必须要切换才能让CPU可以执行不同的进程,但是什么时候切换也是一个问题,所以这里还引入了时间片轮转,就是让进程运行固定的时间然后切换到下一个进程。

所以并发就是通过两点来实现:

  • 进程间切换

  • 时间片轮转

所以我们的并发就是,基于进程间切换的时间片轮转算法。

进程间如何切换

既然我们知道进程是通过切换和时间片轮转来实现的并发,那么进程是如何切换的?

概念铺设

PC指针

我们的计算机时如何知道我们的程序执行到哪一步的?

由于我们的进程时需要切换的,所以我们进程再次被切换到CPU上执行到时候,那么我们的计算机时如何知道该程序被执行到哪一步的?

函数计数器(pc指针):就是通过函数计数器,也称为PC指针,来实现。

如果CPU想再次执行我们该程序的代码,那么CPU就会执行pc指针的下一条代码。

上下文

在提这个概念之前,我们先用一个场景来描述一下。

场景:

你有一个要去当兵的朋友,你的朋友被部队选上了,然后你的朋友很高兴,回宿舍后什么都不管第二天就走了,然后当了两年兵回来后,发现自己宿舍的东西没了,自己的学籍也没了,因为在这两年里面,学校不知道你的朋友当兵去了,然后由于你的朋友每天都不上课,所以被学校开除了学籍。

场景:

还是你的朋友,同样被选上了,这一次你的朋友回宿舍后收拾好了自己的行囊,然后给辅导员也说了这个事情,辅导员帮你的朋友办理了各种手续以及档案等你曾经的记录,然后让你的朋友带走,这次你的朋友回来后把档案那些东西又交给了学校,学校帮忙恢复了学习,然后你的朋友又可以开始正常上课了。

通过上面的这两个故事,我们感觉到了什么?那么如果我们一个CPU要被切换出去的时候,CPU曾经的数据要怎么办?

在我们的 CPU 中有很多寄存器,这些寄存器就是保存的是当前进程的数据,如果我们要切换走一个进程的时候,我们需要把这些寄存器里面的数据也让该进程带走,好让该进程下一次回来的时候在把上一次运行的数据带过来,继续运行。

所以,寄存器里面的数据就是 “上下文” 。

而进程就必须把上下文保护好,好让下一次运行的时候知道如何运行。

概念布设完毕,所以进程间是如何切换的?

进程切换的要求:

  • 保护上下文:将寄存器里面的数据让进程保存起来。

  • 恢复上下文:当一个进程恢复的时候,需要先将它的上下文加载进去。

进程的特点就到这里,我们也说了进程的并发,也说了为什么可以实现并发,还有并发的条件,以及实现并发条件之一的进程切换的部分问题。

环境变量

在说这个概念之前,我们想先看一下环境变量,然后我们正在说环境变量的概念。

PATH

PATH 是一个系统中的环境变量,那么如何查看PATH呢?

[lxy@hecs-165234 linux5]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lxy/.local/bin:/home/lxy/bin

我们想要查看 PATH 我们可以 echo 然后 $ + 环境变量就可以查看。

那么这个PATH 是什么呢?

我们现在先写一个代码来看一下。

int main()
{
  for(int i = 0; i < 10; ++i)
    printf("myproc: [%d]\n", i);
  return 0;
}

我们然后编译这个代码,我们运行它。

[lxy@hecs-165234 linux5]$ ./myproc 
myproc: [0]
myproc: [1]
myproc: [2]
myproc: [3]
myproc: [4]
myproc: [5]
myproc: [6]
myproc: [7]
myproc: [8]
myproc: [9]

我们运行的时候 ./myproc 我们前面说过,其实我们的指令也是代码,那么为什么我们的指令就不用表明路劲呢?

因为我们的指令会自己查找,而在哪查找呢?就是在 PATH 这个环境变量中。

/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lxy/.local/bin:/home/lxy/bin

我们就会在上面的这些路劲里面查找我们的指令,上面这些路劲就是我们的默认指令查找路劲。

如果我们想要自己的程序也不用指明路劲呢?

修改PATH

我们只需要把我们这个程序的路劲添加到 PATH 中,那我们我们就不用指明路劲了,下面我们看一下如何添加。

[lxy@hecs-165234 linux5]$ PATH=/home/lxy/108/linux5

如果我们之间这样就是把 PATH 给覆盖了,并不是添加了当前路劲,所以我们应该如何添加呢?

[lxy@hecs-165234 linux5]$ PATH=$PATH:/home/lxy/108/linux5

下面在查看一下 PATH

[lxy@hecs-165234 linux5]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lxy/.local/bin:/home/lxy/bin:/home/lxy/108/linux5

我们就添加进来了,下面看一下是否可以不用路劲就可以执行。

[lxy@hecs-165234 linux5]$ myproc
myproc: [0]
myproc: [1]
myproc: [2]
myproc: [3]
myproc: [4]
myproc: [5]
myproc: [6]
myproc: [7]
myproc: [8]
myproc: [9]

确实可以执行,实际上,这个 PATH环境变量是临时的,我们的 PATH 环境变量实际上实在系统中的,然后 bash 启动的时候读取的,所以我们可以随便修改这个环境变量,如果修改错了,我们直接重启 bash 就可以了,所以我们直接改掉 PATH 路劲然后我们看那些指令是否就不能用了。

[lxy@hecs-165234 linux5]$ PATH=/
[lxy@hecs-165234 linux5]$ ll
-bash: ls: command not found
[lxy@hecs-165234 linux5]$ ls
-bash: ls: command not found
[lxy@hecs-165234 linux5]$ cd ..
[lxy@hecs-165234 108]$ cd linux5

我们看到我们的 ll ls 部分指令就使用不了了,但是还是有一些指令可以使用。

我们下面重启一下 bash 就可以了。

我们下面在看两个环境变量。

HOME

我们直接打印查看。

[lxy@hecs-165234 linux5]$ echo $HOME
/home/lxy

我们当前的 lxy 用户查看的 HOME,就是上面的这个样子,下面我们换 root 在查看一下。

[root@hecs-165234 lxy]# echo $HOME
/root

我们的 root 用户的 HOME 环境变量就是上面的这个样子。

SHELL

在看一个 SHELL环境变量。

[lxy@hecs-165234 linux5]$ echo $SHELL
/bin/bash

SHELL 就是我们使用的 shell 是什么,我们这里使用的 shell就是 bash。

当然我们的环境变量不止这么一些,我们怎么样查看全部的环境变量呢?

env

查看全部的环境变量。

[lxy@hecs-165234 linux5]$ env
XDG_SESSION_ID=6727
HOSTNAME=hecs-165234
TERM=xterm
SHELL=/bin/bash
HISTSIZE=10000
SSH_CLIENT=123.138.70.232 62136 22
SSH_TTY=/dev/pts/0
USER=lxy
LD_LIBRARY_PATH=:/home/lxy/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/lxy
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lxy/.local/bin:/home/lxy/bin
PWD=/home/lxy/108/linux5
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/home/lxy
LOGNAME=lxy
SSH_CONNECTION=123.138.70.232 62136 192.168.0.70 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/1000
HISTTIMEFORMAT=%F %T lxy 
_=/usr/bin/env
OLDPWD=/home/lxy/108

上面1就是我们全部的环境变量。

我们挑一些介绍一下。

HOSTNAME=hecs-165234

HOSTNAME:就是主机名

SHELL=/bin/bash

SHELL:我们前面介绍了。

HISTSIZE=10000

HISTSIZE:当我们 history 的时候我们就会打印出我们的历史指令,而我们的历史指令的保存是由个数限制的,而 HISTSIZE 就是最大的存储历史指令的限制。

SSH_TTY=/dev/pts/0

这个就是表示我们 bash 输出的时候往哪里输出,我们可以在启动一个然后我们 echo 向这个里面写入 hello

USER=lxy

USER:表示当前的使用者。

PWD=/home/lxy/108/linux5

PWD:表示我们当前文件的路劲。

OLDPWD=/home/lxy/108

OLDPWD:表示我们上一次在那个路劲下。

[lxy@hecs-165234 linux5]$ cd /
[lxy@hecs-165234 /]$ cd -
/home/lxy/108/linux5
[lxy@hecs-165234 linux5]$ cd -
/
[lxy@hecs-165234 /]$ cd -
/home/lxy/108/linux5

cd - 表示就是去上一次的路劲。

上面就是我们的环境变量。

除了我们上面使用命令行操作查看环境变量,其实我们还可以使用函数来查看环境变量。

在谈下面的环境变量之前,这里先谈一个叫命令行参数。

命令行参数

什么是命令行参数?

在我们输入指令的时候,后满经常会带一些选项,而这些雪乡就是命令行参数。

实际上,在C语言或者C++中的 main 函数也是可以带命令行参数的,只是我们之前的环境都基本是在 windows 下,所以没有命令,我们也就接触不到命令行参数,我们先写一个程序看一下。

int main(int argc, char* argv[])
{
  if(argc != 2)
  {
    printf("需要两个参数\n");
    return 0;
  }
  printf("OK\n");
  return 0;
}

这里我们看这一段代码,我们的 main 函数实际上可以带几个参数,其中这里带了两个参数,一个 argc 一个 argv。

argc:表示传过来多少个命令行参数,其中最少就是1个,也就是运行该函数的参数。

argv:表示命令行参数的里面传过来的字符串,我们的argv里面存到就是一个char* 的指针。

下面我们运行该函数看一下。

首先我们只有一个参数,也就是直接运行该函数。

[lxy@hecs-165234 linux5]$ ./myproc 
需要两个参数

下面我们传入参数,随便传入一个参数。

[lxy@hecs-165234 linux5]$ ./myproc -a
OK
[lxy@hecs-165234 linux5]$ ./myproc kkkkkk
OK

这里的参数什么都可以,只要由两个参数就可以了。

打印命令行参数

既然我们可以拿到命令行参数,也有命令行参数的个数,那么我们就可以打印它。

int main(int argc, char* argv[])
{
  for(int i = 0; i < argc; ++i)
    printf("argv[%d]: %s\n", i, argv[i]);

  return 0;
}

这样就可以打印命令行参数了。

我们下面运行改代码试一下。

只有一个参数。

[lxy@hecs-165234 linux5]$ ./myproc 
argv[0]: ./myproc

多个参数。

[lxy@hecs-165234 linux5]$ ./myproc -a -b -c hello
argv[0]: ./myproc
argv[1]: -a
argv[2]: -b
argv[3]: -c
argv[4]: hello

通过函数获得环境变量

getenv

SYNOPSIS
       #include <stdlib.h>

       char *getenv(const char *name);

getenv 函数传入一个环境变量名,然后返回环境变量的值。

下面使用程序来看一下。

int main(int argc, char* argv[])
{
  if(argc != 2)
  {
    printf("需要环境变量\n");
  }
  else 
  {
    printf("%s : %s\n", argv[1], getenv(argv[1]));
  }
  return 0;
}

这里我们通过命令行参数的方式传入环境变量名,然后使用 getenv 函数来获得环境变量。

这里我们直接传入PATH试一下。

[lxy@hecs-165234 linux5]$ ./myproc PATH
PATH : /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lxy/.local/bin:/home/lxy/bin

这里我们获得了环境变量。

下面我们使用环境变量来查看我们的用户,我们分别会使用 root 用户和普通用户来查看。

int main()
{
  if(strcmp(getenv("USER"), "root") == 0)
  {
    printf("无视权限\n");
  }
  else 
  {
    printf("普通用户\n");
  }
  return 0;
}

使用普通用户。

[lxy@hecs-165234 linux5]# ./myproc 
普通用户

下面使用 root 用户。

[root@hecs-165234 linux5]# ./myproc 
无视权限

所以这也就是我们的的权限问题。

命令行参数 env

在 main 函数中的命令行参数其实还可以传入一个参数,就是环境变量。

在打印命令行参数前,我们先说明一下,其实我们的命令行参数和环境变量env中最后一个指针都是null,所以即使我们不适用 argv 也可以打印。

int main(int argc, char* argv[], char* env[])
{
  for(int i = 0; argv[i]; ++i)
    printf("argv[%d]: %s\n", i, argv[i]);
  return 0;
}

下面传入参数打印。

[lxy@hecs-165234 linux5]$ ./myproc -a -b -c -d
argv[0]: ./myproc
argv[1]: -a
argv[2]: -b
argv[3]: -c
argv[4]: -d

那么下面我们也就直接打印一下我们的 env 环境变量。

[lxy@hecs-165234 linux5]$ ./myproc 
env[0]: XDG_SESSION_ID=6739
env[1]: HOSTNAME=hecs-165234
env[2]: TERM=xterm
env[3]: SHELL=/bin/bash
env[4]: HISTSIZE=10000
env[5]: SSH_CLIENT=123.139.60.208 35357 22
env[6]: SSH_TTY=/dev/pts/0
env[7]: USER=lxy
env[8]: LD_LIBRARY_PATH=:/home/lxy/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
env[9]: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
env[10]: MAIL=/var/spool/mail/lxy
env[11]: PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lxy/.local/bin:/home/lxy/bin
env[12]: PWD=/home/lxy/108/linux5
env[13]: LANG=en_US.UTF-8
env[14]: HISTCONTROL=ignoredups
env[15]: SHLVL=1
env[16]: HOME=/home/lxy
env[17]: LOGNAME=lxy
env[18]: SSH_CONNECTION=123.139.60.208 35357 192.168.0.70 22
env[19]: LESSOPEN=||/usr/bin/lesspipe.sh %s
env[20]: XDG_RUNTIME_DIR=/run/user/1000
env[21]: HISTTIMEFORMAT=%F %T lxy 
env[22]: _=./myproc
env[23]: OLDPWD=/home/lxy/108

所以这样也可以打印环境变量。

通过上面的学习,我们可以看一下环境变量了。

我们在上面发现环境变量是可以变化的,当我们登录不同的账户的时候环境变量中的UESR就会变化,我们可以知道环境变量是动态的可以变化的。

在而且我们的环境变量实际上是存储在系统中的,每一次打开bash就会加载,所以我们的环境变量也是居于持久性。

在main函数中,我们看到我们main函数还可以传入 env 变量,所以我们的 env 实际上是可以被所有的子进程继承的,由于我们的进程都是 bash 帮我们创建,所以我们的所有的子进程都是可以有环境变量。

其实我们的环境变量还是可以修改的,我们看一下。

修改环境变量

我们现在想自己定义一个属于我们自己的环境变量,那么该怎么办呢?

[lxy@hecs-165234 linux5]$ MYVALUE=10001

我们上面这样可以吗?

实际上是不可以的,这样定义的话实际上是“本地变量”。

我们查看一下是查不到的。

[lxy@hecs-165234 linux5]$ env | grep MVALUE
[lxy@hecs-165234 linux5]$ 

那么我们的环境变量怎么定义。

[lxy@hecs-165234 linux5]$ export MYVALUE
[lxy@hecs-165234 linux5]$ env | grep MYVALUE
MYVALUE=10001

我们可以将本地变量前面加一个 export 就可以变为环境变量。

那么怎么删除呢?

[lxy@hecs-165234 linux5]$ unset MYVALUE
[lxy@hecs-165234 linux5]$ env | grep MYVALUE
[lxy@hecs-165234 linux5]$

环境变量总结

  • 全局性

  • 动态

  • 持久

  • 可修改

其实不仅仅有这些特性,还有一些,想了解的可以查一下。

本地变量 & 内建命令

最后一个话题,我们前面提到的本地变量和内建命令。

查看本地变量

set命令:

这里为了方便知道我们查到的是本地变量,我们可以先定义一个本地变量的值。

[lxy@hecs-165234 linux5]$ MYVALUE=10000
[lxy@hecs-165234 linux5]$ set | grep  MYVALUE
MYVALUE=10000

下面我们看一下本地变量有一些什么。

由于太多我们只挑几个看一下。

PS1='[\u@\h \W]\$ '
PS2='> '
PS4='+ '

我们这三个,实际上就是本地变量,其中 PS1 就是表示命令行解释器的提示符 我们的普通用户就是 $

而下面的 > 就是还可以输入命令

[lxy@hecs-165234 linux5]$ ls \
> -a\
> -d\
> 

本地变量其实只会在本BASH中有效。

内建命令

我们现在来看一个操作。

[lxy@hecs-165234 linux5]$ MYVALUE=19999
[lxy@hecs-165234 linux5]$ echo $MYVALUE
19999

我们前面不是说,我们的这些指令实际上就是程序吗,那么我们的程序就是 bash 创建子进程来的,但是我们的 MYVALUE 是一个本地变量,本地变量子进程不是不会继承吗?那么echo是怎么样显示出来的?

这里就要纠正之前的一个说法了,其实我们的指令,不一定bash会创建子进程,如果是一些比较安全的指令,那么还是bash自己执行的。

所以我们的命令实际上是由两种:

  • 常规命令:bash创建子进程执行。

  • 内建命令:bash亲自执行,自己调用函数。

还有一个内建命令,比如 cd

下面我们写一个代码来看一下cd命令

首先介绍一个函数

SYNOPSIS
       #include <unistd.h>

       int chdir(const char *path);
DESCRIPTION
       chdir() changes the current working directory of the calling process to the directory specified in path.

该函数传入一个路劲,然后可以修改该进程的路劲。

int main(int argc, char* argv[])
{
  if(argc != 2)
  {
    printf("请输入修改路劲\n");
  }
  else 
  {
    sleep(20);
    printf("开始修改路劲\n");
    chdir(argv[1]);
    printf("路劲修改结束\n");
    sleep(20);
  }
  return 0;
}

我们在休眠的过程中查看我们的该进程的路劲,然后休眠后在查看我们的路劲。

[lxy@hecs-165234 linux5]$ ./myproc /
开始修改路劲
路劲修改结束

在我们休眠前我们查到

lrwxrwxrwx 1 lxy lxy 0 Aug  5 19:51 cwd -> /home/lxy/108/linux5

休眠后

lrwxrwxrwx 1 lxy lxy 0 Aug  5 19:51 cwd -> /

这里看到我们确实修改成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/63624.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript(四)DOM及CSS操作

1、DOM简介 DocumentType: Html的声明标签 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Docume…

从零开始,开发自己的微信小程序小白也能搞定

微信小程序已经成为了很多创业者实现梦想的利器。乔拓云平台提供了一套完整的小程序创建流程&#xff0c;让你轻松打造属于自己的小程序商城。下面就跟随这篇文章&#xff0c;一步一步来看如何创建一个成功的微信小程序商城吧&#xff01; 首先&#xff0c;你需要登录乔拓云平台…

【数据结构】实现单链表的增删查

目录 1.定义接口2.无头单链表实现接口2.1 头插addFirst2.2 尾插add2.3 删除元素remove2.4 修改元素set2.5 获取元素get 3.带头单链表实现接口3.1 头插addFirst3.2 尾插add3.3 删除元素remove3.4 判断是否包含元素element 1.定义接口 public interface SeqList<E>{//默认…

第九节 文件操作

文章目录 1. 引言2. 基本的文件操作2.1 打开文件2.1.1 mode 访问模式2.1.2 文件不存在,则创建文件2.1.3 二进制打开文件2.1.4 打开文件时&#xff0c;指定编码方式 2.2 关闭文件2.2.1 with 打开语句结构 2.3 文件的读写2.3.1 写入文件内容2.3.2 读取文件2.3.2.1 read&#xff0…

TCP的三次握手四次挥手

TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。 三次握手&#xff1a;为了对每次发送的数据量进行跟踪与协商&#xff0c;确保数据段的发送和接收同步&#xff0c;根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系&#xff0c;并建立虚连接。 四次挥手&a…

JVM系统优化实践(24):ZGC(一)

您好&#xff0c;这里是「码农镖局」CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 截止到目前&#xff0c;算上ZGC&#xff0c;Java一共有九种类型的GC&#xff0c;它们分别是&#xff1a; 1、Serial GC 串行/作用于新生代/复制算法/响应速度优先/适用于单…

pointpillars在Ubuntu2004训练的总结

1、找到pointpcdet-master之后在此打开终端输入code进入VScode界面 code 2、激活pp环境 conda activate pp 3、cd进入tools cd tools 4、将kitti数据集准备好放入data路径下之后开始训练 python train.py --cfg_file cfgs/kitti_models/pointpillar.yaml 5、训练完成之…

GraphGT: Machine Learning Datasets for Graph Generation and Transformation

一、文章来源 > Du Y, Wang S, Guo X, et al. Graphgt: Machine learning datasets for graph generation and transformation[C]//Thirty-fifth Conference on Neural Information Processing Systems Datasets and Benchmarks Track (Round 2). 2021.二、概述 1、文章提出…

CMU-CERT内部威胁数据集 r4.2版本介绍

CMU-CERT内部威胁数据集 r4.2版本介绍 一、相关介绍二、CMU-CERT r4.2版本内容三、重大变更 一、相关介绍 “CMU”是卡内基梅隆大学&#xff08;Carnegie Mellon University&#xff09;的简称。 “CERT”是卡内基梅隆大学的一个研究中心叫“CERT”&#xff0c;主要研究内部威…

汇川伺服常见故障处理

伺服系统故障拓扑图 Er.941 变更参数需重新上电生效 产生机理:伺服驱动器的功能码属性“生效时间”为“再次通电”时,该功能码参数值变更后,驱动器提醒用户需要重新上电。 原因 确认方法 处理措施 变更了再次通电后更改生效的功能码 确认是否更改了“生效时间”为“重新上电…

PLC拉格朗日插值(SCL、ST计算源代码)

插值是对函数进行近似的基本方法,这篇博客主要介绍常用的拉格朗日插值法, Lagrange插值法不太清楚的同学,可以看看数值计算和分析类书籍,网上有很多C语言的拉格朗日插值算法,这里我们主要给出在PLC里利用ST,SCL语言完成拉格朗日插值计算。 1、拉格朗日插值FC 插值法可以…

状态模式——对象状态及其转换

1、简介 1.1、概述 在软件系统中&#xff0c;有些对象也像水一样具有多种状态&#xff0c;这些状态在某些情况下能够相互转换&#xff0c;而且对象在不同的状态下也将具有不同的行为。为了更好地对这些具有多种状态的对象进行设计&#xff0c;可以使用一种被称为状态模式的设…

如何把pdf转成cad版本?这种转换方法非常简单

将PDF转换成CAD格式的优势在于&#xff0c;CAD格式通常是用于工程设计和绘图的标准格式。这种格式的文件可以在计算机上进行编辑和修改&#xff0c;而不需要纸质副本。此外&#xff0c;CAD文件通常可以与其他CAD软件进行交互&#xff0c;从而使得工程设计和绘图过程更加高效和精…

fetch-github-hosts间隔一年大更新v2.6发布,多端支持

前言 fetch-github-hosts是一款同步 github hosts 的工具&#xff0c;用于帮助您解决github时而无法访问的问题。在间隔了一年之久的时间&#xff0c;最近抽空将fetch-github-hosts的依赖及UI进行了一波大更新&#xff0c;同时也增加了一些实用的功能。 主要更新 更新了基础依…

安全渗透知识总结二

目录 一、html实体编码 1、Unicode字符编码 2、字符的数字表示 3、常见实体编码 4、url 协议 主机 http状态码 http常用的状态码 端口 常见协议端口 查询参数 锚点 url字符 urlcode字符 绝对url和相对url 二、字符编码 Ascll字符集 html字符集 html的url编码 …

thinkphp8.0多应用模式下提示控制器不存在

thinkphp 8.0 开启多应用模式 1、按照官方文档说明 &#xff0c;已经安装了 think-multi-app composer require topthink/think-multi-app 2、控制器的命名空间也没写错。 3、访问路径与目录名、控制器、方法名一样&#xff0c;访问地址是没错的。 4、网上有说&#xff0c;在…

ubuntu调整路由顺序

Ubuntu系统跳转路由顺序 1、安装ifmetric sudo apt install ifmetric2、查看路由 route -n3、把Iface下面的eth1调到第一位 sudo ifmetric eth1 0命令中eth1是网卡的名称&#xff0c;更改网卡eth1的跃点数&#xff08;metric值&#xff09;为0&#xff08;数值越小&#xf…

Java实现Google授权登录,OAuth 2.0登录

首先创建OAuth 2.0 客户端 ID 配置url&#xff0c;必须是https的&#xff0c;同时复制好客户端id 和密钥 配置回调url /*** Google授权登录跳转。但是会重定向&#xff0c;建议前端跳转** 前端js* // 构建 Google 授权 URL* const authParams new URLSearchParams({* resp…

java linq多字段排序时间比较

public static void main(String[] args) {//100万条数据List<CrmInvestSaleUserCount> waitAssignUserList new ArrayList<>();for (int i 0; i < 1000000; i) {waitAssignUserList.add(new CrmInvestSaleUserCount().setSales_username("test" i…

单元测试之 - Spring框架提供的单元/集成测试注解

Spring框架提供了很多注解来辅助完成单元测试和集成测试(备注&#xff1a;这里的集成测试指容器内部的集成测试&#xff0c;非系统间的集成测试)&#xff0c;先看看Spring框架提供了哪些注解以及对应的作用。RunWith(SpringRunner.class) / ExtendWith(SpringExtension.class)&…