首页 Linux正文

Linux c 程序设计考试 复习

webpro Linux 2019-08-09 146 2

7、Linux vi/vim

所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在。

但是目前我们使用比较多的是 vim 编辑器。

vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正确性,方便程序设计。

相关文章:史上最全Vim快捷键键位图 — 入门到进阶


什么是 vim?

Vim是从 vi 发展出来的一个文本编辑器。代码补完、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。

简单的来说, vi 是老式的字处理器,不过功能已经很齐全了,但是还是有可以进步的地方。 vim 则可以说是程序开发者的一项很好用的工具。

连 vim 的官方网站 (http://www.vim.org) 自己也说 vim 是一个程序开发工具而不是文字处理软件。

vim 键盘图:


vi/vim 的使用

基本上 vi/vim 共分为三种模式,分别是命令模式(Command mode)输入模式(Insert mode)底线命令模式(Last line mode)。 这三种模式的作用分别是:

命令模式:

用户刚刚启动 vi/vim,便进入了命令模式。

此状态下敲击键盘动作会被Vim识别为命令,而非输入字符。比如我们此时按下i,并不会输入一个字符,i被当作了一个命令。

以下是常用的几个命令:

  • i 切换到输入模式,以输入字符。

  • x 删除当前光标所在处的字符。

  • : 切换到底线命令模式,以在最底一行输入命令。

若想要编辑文本:启动Vim,进入了命令模式,按下i,切换到输入模式。

命令模式只有一些最基本的命令,因此仍要依靠底线命令模式输入更多命令。

输入模式

在命令模式下按下i就进入了输入模式。

在输入模式中,可以使用以下按键:

  • 字符按键以及Shift组合,输入字符

  • ENTER,回车键,换行

  • BACK SPACE,退格键,删除光标前一个字符

  • DEL,删除键,删除光标后一个字符

  • 方向键,在文本中移动光标

  • HOME/END,移动光标到行首/行尾

  • Page Up/Page Down,上/下翻页

  • Insert,切换光标为输入/替换模式,光标将变成竖线/下划线

  • ESC,退出输入模式,切换到命令模式

底线命令模式

在命令模式下按下:(英文冒号)就进入了底线命令模式。

底线命令模式可以输入单个或多个字符的命令,可用的命令非常多。

在底线命令模式中,基本的命令有(已经省略了冒号):

  • q 退出程序

  • w 保存文件

按ESC键可随时退出底线命令模式。




7、Linux who命令

Linux who命令用于显示系统中有哪些使用者正在上面,显示的资料包含了使用者 ID、使用的终端机、从哪边连上来的、上线时间、呆滞时间、CPU 使用量、动作等等。

使用权限:所有使用者都可使用。

语法

who - [husfV] [user]

参数说明

  • -H 或 --heading:显示各栏位的标题信息列;

  • -i 或 -u 或 --idle:显示闲置时间,若该用户在前一分钟之内有进行任何动作,将标示成"."号,如果该用户已超过24小时没有任何动作,则标示出"old"字符串;

  • -m:此参数的效果和指定"am i"字符串相同;

  • -q 或--count:只显示登入系统的帐号名称和总人数;

  • -s:此参数将忽略不予处理,仅负责解决who指令其他版本的兼容性问题;

  • -w 或-T或--mesg或--message或--writable:显示用户的信息状态栏;

  • --help:在线帮助;

  • --version:显示版本信息。

实例

显示当前登录系统的用户

# who  //显示当前登录系统的用户root   tty7     2014-05-13 12:12 (:0)root   pts/0    2014-05-14 17:09 (:0.0)root   pts/1    2014-05-14 18:51 (192.168.1.17)root   pts/2    2014-05-14 19:48 (192.168.1.17)

显示标题栏

# who -HNAME   LINE     TIME       COMMENT
root   tty7     2014-05-13 12:12 (:0)root   pts/0    2014-05-14 17:09 (:0.0)root   pts/1    2014-05-14 18:51 (192.168.1.17)root   pts/2    2014-05-14 19:48 (192.168.1.17)

显示用户登录来源

# who -l -HNAME   LINE     TIME       IDLE     PID COMMENT
LOGIN  tty4     2014-05-13 12:11        852 id=4LOGIN  tty5     2014-05-13 12:11        855 id=5LOGIN  tty2     2014-05-13 12:11        862 id=2LOGIN  tty3     2014-05-13 12:11        864 id=3LOGIN  tty6     2014-05-13 12:11        867 id=6LOGIN  tty1     2014-05-13 12:11       1021 id=1

显示终端属性

# who -T -HNAME    LINE     TIME       COMMENT
root   + tty7     2014-05-13 12:12 (:0)root   + pts/0    2014-05-14 17:09 (:0.0)root   - pts/1    2014-05-14 18:51 (192.168.1.17)root   - pts/2    2014-05-14 19:48 (192.168.1.17)

只显示当前用户

# who -m -HNAME   LINE     TIME       COMMENT
root   pts/1    2014-05-14 18:51 (192.168.1.17)

精简模式显示

# who -qroot root root root# users=4




6、基本命令(此处大部分语法教程来自 www.runoob.com,runoob版权所有,这里粘贴仅供学习)

6.1、ls 指令

root@DESKTOP-P9B04K1:~# ls -l
total 0
drwxr-xr-x 0 root root 512 Jul  5 08:20 Desktop
drwxr-xr-x 0 root root 512 Jun 19 08:54 Documents
drwxr-xr-x 0 root root 512 Jun 20 07:17 Downloads
drwxr-xr-x 0 root root 512 Jun 19 08:54 Music
drwxr-xr-x 0 root root 512 Jun 19 08:54 Pictures
drwxr-xr-x 0 root root 512 Jun 19 08:54 Public
drwxr-xr-x 0 root root 512 Jun 19 08:54 Templates
drwxr-xr-x 0 root root 512 Jun 19 08:54 Videos

root@DESKTOP-P9B04K1:~# ls /
bin   cache  dev  home  lib    media  opt   root  sbin  srv  tmp  var
boot  data   etc  init  lib64  mnt    proc  run   snap  sys  usr

root@DESKTOP-P9B04K1:~# ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos
root@DESKTOP-P9B04K1:~# ls -a
.              .cache   Documents      .local    Pictures  Public       .viminfo     .xsession-errors
..             .config  Downloads      .mozilla  .pki      Templates    .vnc
.bash_history  .dbus    .gvfs          Music     .presage  .thumbnails  .Xauthority
.bashrc        Desktop  .ICEauthority  .nano     .profile  Videos       .xsession

root@DESKTOP-P9B04K1:~# ls -l
total 0
drwxr-xr-x 0 root root 512 Jul  5 08:20 Desktop
drwxr-xr-x 0 root root 512 Jun 19 08:54 Documents
drwxr-xr-x 0 root root 512 Jun 20 07:17 Downloads
drwxr-xr-x 0 root root 512 Jun 19 08:54 Music
drwxr-xr-x 0 root root 512 Jun 19 08:54 Pictures
drwxr-xr-x 0 root root 512 Jun 19 08:54 Public
drwxr-xr-x 0 root root 512 Jun 19 08:54 Templates
drwxr-xr-x 0 root root 512 Jun 19 08:54 Videos

root@DESKTOP-P9B04K1:~# ls /|grep -n lib
9:lib
10:lib64

root@DESKTOP-P9B04K1:~# ls /|grep lib
lib
lib64

6.2、chmod更改权限

Linux文件属性有两种设置方法,一种是数字,一种是符号。

Linux文件的基本权限就有九个,分别是owner/group/others三种身份各有自己的read/write/execute权限。

先复习一下刚刚上面提到的数据:文件的权限字符为:『-rwxrwxrwx』, 这九个权限是三个三个一组的!其中,我们可以使用数字来代表各个权限,各权限的分数对照表如下:

  • r:4

  • w:2

  • x:1

每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的,例如当权限为: [-rwxrwx---] 分数则是:

  • owner = rwx = 4+2+1 = 7

  • group = rwx = 4+2+1 = 7

  • others= --- = 0+0+0 = 0

root@DESKTOP-P9B04K1:~/Desktop# ll
total 0
drwxr-xr-x 0 root root 512 Aug 10 10:23 ./
drwx------ 0 root root 512 Aug 10 10:23 ../
-rw-rw-rw- 1 root root   6 Aug 10 10:23 test.txt


root@DESKTOP-P9B04K1:~/Desktop# chmod 777 test.txt
root@DESKTOP-P9B04K1:~/Desktop# ll
total 0
drwxr-xr-x 0 root root 512 Aug 10 10:23 ./
drwx------ 0 root root 512 Aug 10 10:23 ../
-rwxrwxrwx 1 root root   6 Aug 10 10:23 test.txt*


root@DESKTOP-P9B04K1:~/Desktop# chmod 640 test.txt
root@DESKTOP-P9B04K1:~/Desktop# ll
total 0
drwxr-xr-x 0 root root 512 Aug 10 10:23 ./
drwx------ 0 root root 512 Aug 10 10:23 ../
-rw-r----- 1 root root   6 Aug 10 10:23 test.txt

6.3、处理目录的常用命令

  • ls: 列出目录

  • cd:切换目录

  • pwd:显示目前的目录

  • mkdir:创建一个新的目录

  • rmdir:删除一个空的目录

  • cp: 复制文件或目录

  • rm: 移除文件或目录

  • mv: 移动文件与目录,或修改文件与目录的名称

你可以使用 man [命令] 来查看各个命令的使用文档,如 :man cp。


ls (列出目录)

语法:

[root@www ~]# ls [-aAdfFhilnrRSt] 目录名称[root@www ~]# ls [--color={never,auto,always}] 目录名称[root@www ~]# ls [--full-time] 目录名称

选项与参数:

  • -a :全部的文件,连同隐藏档( 开头为 . 的文件) 一起列出来(常用)

  • -d :仅列出目录本身,而不是列出目录内的文件数据(常用)

  • -l :长数据串列出,包含文件的属性与权限等等数据;(常用)

root@DESKTOP-P9B04K1:~/Desktop# ls
test.txt
root@DESKTOP-P9B04K1:~/Desktop# ls -l
total 0
-rw-r----- 1 root root 6 Aug 10 10:23 test.txt
root@DESKTOP-P9B04K1:~/Desktop# ls -a
.  ..  test.txt
root@DESKTOP-P9B04K1:~/Desktop# ls -al
total 0
drwxr-xr-x 0 root root 512 Aug 10 10:23 .
drwx------ 0 root root 512 Aug 10 10:23 ..
-rw-r----- 1 root root   6 Aug 10 10:23 test.txt
root@DESKTOP-P9B04K1:~/Desktop# ls -d
.

cd (切换目录)

cd是Change Directory的缩写,这是用来变换工作目录的命令。

语法:

 cd [相对路径或绝对路径]
root@DESKTOP-P9B04K1:~/Desktop# cd /
root@DESKTOP-P9B04K1:/# cd /root
root@DESKTOP-P9B04K1:~#

pwd (显示目前所在的目录)

pwd 是 Print Working Directory 的缩写,也就是显示目前所在目录的命令。

[root@www ~]# pwd [-P]

选项与参数:

  • -P :显示出确实的路径,而非使用连结 (link) 路径。

root@DESKTOP-P9B04K1:~# pwd
/root
root@DESKTOP-P9B04K1:~# pwd -P
/root
root@DESKTOP-P9B04K1:~# pwd -p
-bash: pwd: -p: invalid option
pwd: usage: pwd [-LP]

# P要大写

实例显示出实际的工作目录,而非连结档本身的目录名而已。

[root@www ~]# cd /var/mail   <==注意,/var/mail是一个连结档
[root@www mail]# pwd/var/mail         <==列出目前的工作目录
[root@www mail]# pwd -P/var/spool/mail   <==怎么回事?有没有加 -P 差很多~
[root@www mail]# ls -ld /var/mail
lrwxrwxrwx 1 root root 10 Sep  4 17:54 /var/mail -> spool/mail
# 看到这里应该知道为啥了吧?因为 /var/mail 是连结档,连结到 /var/spool/mail 
# 所以,加上 pwd -P 的选项后,会不以连结档的数据显示,而是显示正确的完整路径啊!

mkdir (创建新目录)

如果想要创建新的目录的话,那么就使用mkdir (make directory)吧。

语法:

mkdir [-mp] 目录名称

选项与参数:

  • -m :配置文件的权限。

  • -p :帮助你直接将所需要的目录(包含上一级目录)递归创建起来!

实例:请到/tmp底下尝试创建数个新目录看看:

[root@www ~]# cd /tmp[root@www tmp]# mkdir test    <==创建一名为 test 的新目录[root@www tmp]# mkdir test1/test2/test3/test4
mkdir: cannot create directory `test1/test2/test3/test4': 
No such file or directory       <== 没办法直接创建此目录啊!
[root@www tmp]# mkdir -p test1/test2/test3/test4

加了这个 -p 的选项,可以自行帮你创建多层目录!

实例:创建权限为 rwx--x--x 的目录。

[root@www tmp]# mkdir -m 711 test2[root@www tmp]# ls -l
drwxr-xr-x  3 root  root 4096 Jul 18 12:50 test
drwxr-xr-x  3 root  root 4096 Jul 18 12:53 test1
drwx--x--x  2 root  root 4096 Jul 18 12:54 test2

上面的权限部分,如果没有加上 -m 来强制配置属性,系统会使用默认属性。

如果我们使用 -m ,如上例我们给予 -m 711 来给予新的目录 drwx--x--x 的权限。

rmdir (删除空的目录)

语法:

 rmdir [-p] 目录名称

选项与参数:

  • -p :连同上一级『空的』目录也一起删除

删除 runoob 目录

[root@www tmp]# rmdir runoob/

将 mkdir 实例中创建的目录(/tmp 底下)删除掉!

[root@www tmp]# ls -l   <==看看有多少目录存在?drwxr-xr-x  3 root  root 4096 Jul 18 12:50 test
drwxr-xr-x  3 root  root 4096 Jul 18 12:53 test1
drwx--x--x  2 root  root 4096 Jul 18 12:54 test2[root@www tmp]# rmdir test   <==可直接删除掉,没问题[root@www tmp]# rmdir test1  <==因为尚有内容,所以无法删除!rmdir: `test1': Directory not empty
[root@www tmp]# rmdir -p test1/test2/test3/test4
[root@www tmp]# ls -l        <==您看看,底下的输出中test与test1不见了!
drwx--x--x  2 root  root 4096 Jul 18 12:54 test2

利用 -p 这个选项,立刻就可以将 test1/test2/test3/test4 一次删除。

不过要注意的是,这个 rmdir 仅能删除空的目录,你可以使用 rm 命令来删除非空目录。

cp (复制文件或目录)

cp 即拷贝文件和目录。

语法:

[root@www ~]# cp [-adfilprsu] 来源档(source) 目标档(destination)[root@www ~]# cp [options] source1 source2 source3 .... directory

选项与参数:

  • -a:相当於 -pdr 的意思,至於 pdr 请参考下列说明;(常用)

  • -d:若来源档为连结档的属性(link file),则复制连结档属性而非文件本身;

  • -f:为强制(force)的意思,若目标文件已经存在且无法开启,则移除后再尝试一次;

  • -i:若目标档(destination)已经存在时,在覆盖时会先询问动作的进行(常用)

  • -l:进行硬式连结(hard link)的连结档创建,而非复制文件本身;

  • -p:连同文件的属性一起复制过去,而非使用默认属性(备份常用);

  • -r:递归持续复制,用於目录的复制行为;(常用)

  • -s:复制成为符号连结档 (symbolic link),亦即『捷径』文件;

  • -u:若 destination 比 source 旧才升级 destination !

用 root 身份,将 root 目录下的 .bashrc 复制到 /tmp 下,并命名为 bashrc

[root@www ~]# cp ~/.bashrc /tmp/bashrc[root@www ~]# cp -i ~/.bashrc /tmp/bashrc
cp: overwrite `/tmp/bashrc'? n  <==n不覆盖,y为覆盖

rm (移除文件或目录)

语法:

 rm [-fir] 文件或目录

选项与参数:

  • -f :就是 force 的意思,忽略不存在的文件,不会出现警告信息;

  • -i :互动模式,在删除前会询问使用者是否动作

  • -r :递归删除啊!最常用在目录的删除了!这是非常危险的选项!!!


将刚刚在 cp 的实例中创建的 bashrc 删除掉!

[root@www tmp]# rm -i bashrc
rm: remove regular file `bashrc'? y

如果加上 -i 的选项就会主动询问喔,避免你删除到错误的档名!

mv (移动文件与目录,或修改名称)

语法:

[root@www ~]# mv [-fiu] source destination[root@www ~]# mv [options] source1 source2 source3 .... directory

选项与参数:

  • -f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖;

  • -i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!

  • -u :若目标文件已经存在,且 source 比较新,才会升级 (update)

复制一文件,创建一目录,将文件移动到目录中

[root@www ~]# cd /tmp
[root@www tmp]# cp ~/.bashrc bashrc
[root@www tmp]# mkdir mvtest
[root@www tmp]# mv bashrc mvtest

将某个文件移动到某个目录去,就是这样做!

将刚刚的目录名称更名为 mvtest2

[root@www tmp]# mv mvtest mvtest2
# 对于如下指令
[root@www tmp]# mv obj1 obj2
  • 当 obj1为普通文件,obj2在系统中不存在,那么这条指令会将文件名obj1改成obj2

  • 当 obj1为普通文件,obj2为一目录,那么会将obj1移动到obj2中

  • 当 obj1为一目录,obj2为一目录,这条指令会将obj1移动到obj2下成为其子目录

  • 当 obj1为一目录,obj2为一文件,这条指令不会正常执行,会报错: mv: cannot overwrite non-directory 'obj2' with directory 'obj1'




5、Linux 系统目录结构

root@DESKTOP-P9B04K1:~# ls /
bin   cache  dev  home  lib    media  opt   root  sbin  srv  tmp  var
boot  data   etc  init  lib64  mnt    proc  run   snap  sys  usr

树状目录结构:



以下是对这些目录的解释:

  • /bin
    bin是Binary的缩写, 这个目录存放着最经常使用的命令。

  • /boot:
    这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。

  • /dev :
    dev是Device(设备)的缩写, 该目录下存放的是Linux的外部设备,在Linux中访问设备的方式和访问文件的方式是相同的。

  • /etc:
    这个目录用来存放所有的系统管理所需要的配置文件和子目录。

  • /home
    用户的主目录,在Linux中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。

  • /lib
    这个目录里存放着系统最基本的动态连接共享库,其作用类似于Windows里的DLL文件。几乎所有的应用程序都需要用到这些共享库。

  • /lost+found
    这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。

  • /media
    linux系统会自动识别一些设备,例如U盘、光驱等等,当识别后,linux会把识别的设备挂载到这个目录下。

  • /mnt
    系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在/mnt/上,然后进入该目录就可以查看光驱里的内容了。

  • /opt
     这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。

  • /proc
    这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。
    这个目录的内容不在硬盘上而是在内存里,我们也可以直接修改里面的某些文件,比如可以通过下面的命令来屏蔽主机的ping命令,使别人无法ping你的机器:

    echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
  • /root
    该目录为系统管理员,也称作超级权限者的用户主目录。

  • /sbin
    s就是Super User的意思,这里存放的是系统管理员使用的系统管理程序。

  • /selinux
     这个目录是Redhat/CentOS所特有的目录,Selinux是一个安全机制,类似于windows的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。

  • /srv
     该目录存放一些服务启动之后需要提取的数据。

  • /sys

     这是linux2.6内核的一个很大的变化。该目录下安装了2.6内核中新出现的一个文件系统 sysfs 。

    sysfs文件系统集成了下面3种文件系统的信息:针对进程信息的proc文件系统、针对设备的devfs文件系统以及针对伪终端的devpts文件系统。

  • 该文件系统是内核设备树的一个直观反映。

    当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。

  • /tmp
    这个目录是用来存放一些临时文件的。

  • /usr
     这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于windows下的program files目录。

  • /usr/bin:
    系统用户使用的应用程序。

  • /usr/sbin:
    超级用户使用的比较高级的管理程序和系统守护程序。

  • /usr/src:
    内核源代码默认的放置目录。

  • /var
    这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。

  • /run
    是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。如果你的系统上有 /var/run 目录,应该让它指向 run。


在 Linux 系统中,有几个目录是比较重要的,平时需要注意不要误删除或者随意更改内部文件。

/etc: 上边也提到了,这个是系统中的配置文件,如果你更改了该目录下的某个文件可能会导致系统不能启动。

/bin, /sbin, /usr/bin, /usr/sbin: 这是系统预设的执行文件的放置目录,比如 ls 就是在/bin/ls 目录下的。

值得提出的是,/bin, /usr/bin 是给系统用户使用的指令(除root外的通用户),而/sbin, /usr/sbin 则是给root使用的指令。

/var: 这是一个非常重要的目录,系统上跑了很多程序,那么每个程序都会有相应的日志产生,而这些日志就被记录到这个目录下,具体在/var/log 目录下,另外mail的预设放置也是在这里。




4、Linux中重启的两个命令:reboot和init 6之间的区别

Init 6是重新启动机器; reboot也是重新启动机器;

那这两个命令到底有什么区别呢?

对这两个操作使用man命令看到的内容如下:

"init 6" 基于一系列/etc/inittab文件,并且每个应用都会有一个相应shutdown脚本。

"init 6"调用一系列shutdown脚本(/etc/rc0.d/K*)来使系统优雅关机;

'reboot'并不执行这些过程,reboot更是一个kernel级别的命令,

不对应用使用shutdown脚本。

reboot - reboot performs a sync(1M) operation on the disks, andthen amulti- user reboot is initiated. See init(1M) fordetails.init 6 Stop the operating system and reboot to the state defined by the initdefault entry in /etc/inittab.


我们应该在通常情况下使用 init 6.

在出问题的状况下或强制重启时使用reboot


Linux系统有7个运行级别(runlevel):

  • 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动

  • 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆

  • 运行级别2:多用户状态(没有NFS)

  • 运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式

  • 运行级别4:系统未使用,保留

  • 运行级别5:X11控制台,登陆后进入图形GUI模式

  • 运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动




3、ls -l命令结果说明

[root@webpro1 VmwareShare]# ls -l
总用量 88
-rwxrwxrwx. 1 root root 88204 8月   9 08:49 mlocate.rpm
-rwxrwxrwx. 1 root root    56 8月   9 09:07 test
-rwxrwxrwx. 1 root root     7 8月   8 12:20 新文件~
-rwxrwxrwx. 1 root root    15 8月   8 20:02 新文件.txt

对于 - rwx  rwx  rwx

第一列

-文件b可随机存储装置
d目录c串口设备(如鼠标键盘等)
l链接文档p管道文件

rwx

r - 读

w - 写

x - 运行


363003_1227493859FdXT

图片来自 https://www.runoob.com/linux/linux-file-attr-permission.html 菜鸟教程

图片仅供学习




2、父子进程管道通讯

2.1、方式1 重定向I/O

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void){
    int fd[2]; // fd[0]为读 fd[1]为写
    pid_t pid;

    /*创建管道 */
    if(pipe(fd) < 0){
        perror("fail to pipe");
        exit(1);
    }

    /*创建子进程 */
    if((pid = fork()) < 0){
        perror("fail to fork");
        exit(1);
    }else if(pid != 0){
        // 父进程
        close(fd[0]);
        dup(fd[1]);
        printf("我是父进程");
    }else{
        // 子进程
        close(fd[1]);
        dup(fd[0]);
        char str[256];
        fgets(str, sizeof(str), stdin);
        printf("%s\n", str);
    }
}

测试运行

root@DESKTOP-P9B04K1:/mnt/d/phpStudy/WWW/vsCode/linux/c/test# ./run pipe1

--------- project pipe1 start ---------

我是父进程
--------- project pipe1 end ---------


2.2、标准方法

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <limits.h>

#define BUFSZ PIPE_BUF /* PIPE_BUF 管道默认一次性读写数据的长度 , PIPE_BUF大小为<limits.h>中规定*/

int main(void){
    int fd[2]; // fd[0]为读 fd[1]为写
    char buf[BUFSZ];
    pid_t pid;
    ssize_t len;

    /*创建管道 */
    if(pipe(fd) < 0){
        perror("fail to pipe");
        exit(1);
    }

    /*创建子进程 */
    if((pid = fork()) < 0){
        perror("fail to fork");
        exit(1);
    }else if(pid > 0){
        close(fd[0]);                         /*父进程中关闭管道的读出端*/
        write(fd[1], "我是父进程\n", 20);  /*父进程向管道写入数据*/
    }else{
        close(fd[1]);                   /*子进程中关闭管道的写入端*/
        len = read(fd[0], buf, BUFSZ);  /*子进程读取管道数据*/
        if(len < 0){
            perror ( "process failed when read a pipe " );
            exit( 1 );
        }else{
            write(STDOUT_FILENO, buf, len);
            exit(0);
        }
    }
}

测试运行

root@DESKTOP-P9B04K1:/mnt/d/phpStudy/WWW/vsCode/linux/c/test# ./run pipe

--------- project pipe start ---------

我是父进程

--------- project pipe end ---------




1、打开一文本文件,给出字符串(char *pattern)在文件哪些行出现过,在屏幕上显示匹配的行号和改行文本。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


void computed(FILE *fd, char *pattern){
    // windows 中 换行符为 \r\n
    // unix 中 换行符为 \n
    // 因此可以使用 \n 作为统一换行标志

    char ch;                            // 单字符缓存
    int line = 1;                       // 当前行数
    char current_line_content[256];     // 当前行字符串缓存
    int temp_idx = 0;                   // 当前行的匹配列数
    int current_idx = 0;                // 当前行的列数
    int current_status = 0;             // 当前行无匹配成功状态 当一行中有一个匹配后,就不再对其后面的字符串进行比较了

    while((ch = fgetc(fd)) != EOF){
        // 换行后行数+1
        if(ch == '\n'){
            if(current_status){
                printf("line[%d], content[%s]\n", line, current_line_content);
                current_status = 0;
            }
            line++;
            memset(current_line_content, 0, sizeof(current_line_content));
            current_idx = 0;
        }else if(ch == '\r'){
            // 对于win系统忽略掉\r
            continue;
        }else{
            current_line_content[current_idx] = ch;
            current_idx++;
            if(!current_status){
                if(ch == pattern[temp_idx]){
                    temp_idx++;
                    if(pattern[temp_idx] == '\0'){
                        // 匹配成功
                        temp_idx = 0;
                        current_status = 1;
                    }
                }else{
                    // 不匹配从头来
                    temp_idx = 0;
                }
            }
        }
    }
}

int main(int argc, char *argv[]){

    if(argc != 3){
        // 第 0 个参数是运行的文件名
        perror("请传参: ./main filename pattern");
        exit(0);
    }

    char* file_name = (char*)argv[1];
    char* pattern   = (char*)argv[2];

    FILE *fd;     // 文件句柄

    if((fd = fopen(file_name, "r")) == NULL){
        perror("文件打开失败");
        exit(1);
    }

    computed(fd, pattern);

    return 0;
}


测试匹配的文件:find

Mr. liu, would you care for another helping?
No more, thank you. I'm quite full.
Did you enjoy the meal?
I'm so glad you like it.
Thank you very much for your hospitality.

编译程序

g++ -o findstr findstr.c

测试程序1 在find文件中查找包含you字符串的行并输出

./findstr find you

运行结果

root@DESKTOP-P9B04K1:/mnt/d/phpStudy/WWW/vsCode/linux/c/test# ./findstr find you
line[1], content[Mr. liu, would you care for another helping?]
line[2], content[No more, thank you. I'm quite full.]
line[3], content[Did you enjoy the meal?]
line[4], content[I'm so glad you like it.]
line[5], content[Thank you very much for your hospitality.]

测试程序2 在find文件中查找包含Mr字符串的行并输出

root@DESKTOP-P9B04K1:/mnt/d/phpStudy/WWW/vsCode/linux/c/test# ./findstr find Mr
line[1], content[Mr. liu, would you care for another helping?]

测试程序3 输入一个不存在的文件

root@DESKTOP-P9B04K1:/mnt/d/phpStudy/WWW/vsCode/linux/c/test# ./findstr find2 you
文件打开失败: No such file or directory

测试程序4 输入错误的参数个数

root@DESKTOP-P9B04K1:/mnt/d/phpStudy/WWW/vsCode/linux/c/test# ./findstr find
请传参: ./main filename pattern: Success


版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

评论

精彩评论

运行

«   2019年11月   »
123
45678910
11121314151617
18192021222324
252627282930

WebPro统计

Top