3. Linux基本指令(下)|重定向|管道|rm|man|nano|cp|mv|which|alias|cat|<|echo|>|while语句|more|less|head|tail

01. rm指令补充

rm -r xxx

递归式删除,删除目录时需使用

rm -i xxx

删除前问询

rm -f xxx

强制删除

rm -rf *
rm -rf ./*
删除所有文件

删除当前目录下的所有文件
![[Pasted image 20240512163223.png]]

*类似于Linux里的通配符,指定路径下的所有文件
![[Pasted image 20240512163521.png]]

rm在删除时默认不删除隐藏文件
想删除隐藏文件,只能指定

总结
  • 通常删除文件就用rm就行了
  • 删普通文件就rm后面跟文件名
  • 删对应的目录的话就带-r
  • 如果都想强制删除就带-f

02. man指令

Linux的命令有很多参数,我们不可能全记住,我们可以通过查看联机手册获取帮助。访问Linux手册页的命令是 man 语法

常用选项

  • -k 根据关键字搜索联机帮助
  • num 只在第num章节找
  • -a 将所有章节的都显示出来,比如 man printf 它缺省从第一章开始搜索,知道就停止,用a选项,当按下q退出,他会继续往后面搜索,直到所有章节都搜索完毕。

输入

man man

可以在线找到man指令的信息
![[Pasted image 20240512170917.png]]

man手册里一共可以提供9种手册
![[Pasted image 20240512170946.png]]

1号手册
是普通的命令。当默认用man进行指令查找的时候,默认用1号手册,显示和查看可执行程序或shell命令的基本用法
2号手册
是系统调用,如open,write之类的(通过这个,至少可以很方便的查到调用这个函数,需要加什么头文件)
3号手册
是库函数,如printf,fread4是特殊文件,也就是/dev下的各种设备文件
5号手册
是指文件的格式,比如passwd, 就会说明这个文件中各个字段的含义
6号手册
是给游戏留的,由各个游戏自己定义
7号手册
是附件还有一些变量,比如向environ这种全局变量在这里就有说明
8号手册
是系统管理用的命令,这些命令只能由root使用,如ifconfig

退出

输入q

默认查找

比如查找ls指令
![[Pasted image 20240512172338.png]]

man ls

默认使用1号手册
如果不带1,默认在1号手册里先查
查到了直接显示,然后终止查找
如果没查到,接着到2号手册里去找
如果还没找到,继续往后找,依次类推
从1到9,依次往后找,哪个先找到,就显示哪个手册对应的内容

比如查找printf
输入

man printf

![[Pasted image 20240512172542.png]]

右边括号里有1,表示是1号手册
printf在shell里也是一条命令,和printf函数没有任何关系,就是一个可执行程序
![[Pasted image 20240512172832.png]]

可以通过C语言的方式,格式化输出

指定查找

如果想查看printf在库函数里的内容,需要指定手册查找

man 3 printf

![[Pasted image 20240512173025.png]]

可以看到函数的调用、头文件和用例

安装man指令

云服务器,是一个生产环境。
企业里面开发的时候,做一个项目的时候,在开发团队里面
要有三种环境

  1. 开发环境
    程序员自己写代码,调试代码的环境
  2. 测试环境
    测试人员的测试环境
  3. 生产环境
    真实线上环境,写完,测完,真正给用户提供服务的环境
    非常干净的操作系统,不会安装和开发强相关的工具

所以在线上环境里可能查man手册,没有
安装

yum install -y man-pages

apt-get install man

![[Pasted image 20240512184609.png]]

查看man版本
![[Pasted image 20240512184634.png]]

03. nano指令

小工具nano

Linux中的记事本
输入

nano file.txt

![[Pasted image 20240512192239.png]]

打开记事本
可以自由地在里面写东西
![[Pasted image 20240512192440.png]]

比如写一个简单的小程序
![[Pasted image 20240512192522.png]]

下边有指令
^是Ctrl的意思
按住ctrl+x就是退出
![[Pasted image 20240512192623.png]]

点击保存修改
![[Pasted image 20240512192700.png]]

点击回车
就退出来了
![[Pasted image 20240512192836.png]]

可以简单在Linux里写一个文件
通过nano在文件里写入,改的是文件的内容

查看nano版本

输入

nano --version

![[Pasted image 20240512193300.png]]

安装nano

输入

yum install -y nano

apt-get install nano

![[Pasted image 20240512193442.png]]

04. cp指令

语法:cp 源文件或目录 目标文件或目录
功能:复制文件或目录
说明:cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中。若同时指定多个文件或目录,而最后的目的地并非一个已存在的目录,则会出现错误信息
常用选项

  • -f 或 --force 强行复制文件或目录, 不论目的文件或目录是否已经存在
  • -i 或 --interactive 覆盖文件之前先询问用户
  • -r递归处理,将指定目录下的文件与子目录一并处理。若源文件或目录的形态,不属于目录或符号链接,则一律视为普通文件处理
  • -R 或 --recursive递归处理,将指定目录下的文件及子目录一并处理
前提

同级目录下,不允许存在同名文件或同名目录
![[Pasted image 20240512191337.png]]

发现输入两次touch指令后,只出现了一个file.txt文件
因为touch还有第二个功能就是更新时间,所以touch第二次的时候没有报错,但事实上只有一个文件
![[Pasted image 20240512191510.png]]

makdir会报错

拷贝文件到上级目录

输入

cp file.txt ..

将本目录的file文件拷贝到上级目录
![[Pasted image 20240512195544.png]]

上级目录里有file.txt,当前目录里也有file.txt
![[Pasted image 20240512195646.png]]

再查看两个文件的内容,是一模一样的

拷贝文件到同级目录

如果拷贝到当前目录会报错,名字会重复
![[Pasted image 20240512195825.png]]

可以备份文件
输入

cp file.txt file.txt.bak

![[Pasted image 20240512195910.png]]

拷贝目录到上级目录

![[Pasted image 20240512203142.png]]

目前dir目录里有三个文件

把dir目录拷贝到上级目录下
![[Pasted image 20240512203655.png]]

拷贝失败
cp默认只是对文件做拷贝,目录不允许这样操作
可以输入

cp -rf dir ..

![[Pasted image 20240512203831.png]]

拷贝目录到同级目录

如果要拷贝目录到同级目录的话

cp -rf dir dir

这样是不对的,会将dir当作源,dir当作目的地,在dir里面粘贴dir
应当输入

cp -rf dir dir.bak

![[Pasted image 20240512204423.png]]

拷贝的同时修改名字

![[Pasted image 20240512205259.png]]

对于普通文件也适用

拷贝时,可以保证文件名拷贝到新的路径之后不变
也可以指定文件名,拷贝过去时,内容一样,让文件名更改
只要保证同级别目录不影响就可以了

拷贝目录里的内容

![[Pasted image 20240512210850.png]]

比如把test里的内容拷贝到root目录里的dir目录里
输入

cp -rf /root/test/* dir

![[Pasted image 20240512211658.png]]

拷贝会不会拷贝隐藏文件

拷贝过程中默认是把能看到的文件拷贝过去,不知道有隐藏文件,就不会拷贝它,知道有隐藏文件的话,就单独拷贝
不应该把.开头的隐藏文件拷贝过去,因为每个目录里面都有...
如果把隐藏文件拷过去,就意味着也要把...拷过去,此时就会出现目标目录下的文件名重复问题

05. mv指令

mv命令是move的缩写,可以用来移动文件或者将文件改名,是Linux系统下常用的命令,经常用来备份文件或者目录。
语法:mv 源文件或目录 目标文件或目录
功能

  1. 视mv命令中第二个参数类型的不同(是目标文件还是目标目录),mv命令将文件重命名或将其移至一个新的目录中。
  2. 当第二个参数类型是文件时,mv命令完成文件重命名,此时,源文件只能有一个(也可以是源目录名),它将所给的源文件或目录重命名为给定的目标文件名。
  3. 当第二个参数是已存在的目录名称时,源文件或目录参数可以有多个,mv命令将各参数指定的源文件均移至目标目录中。
    常用选项
  • -f :force 强制的意思,如果目标文件已经存在,不会询问而直接覆盖
  • -i :若目标文件 (destination) 已经存在时,就会询问是否覆盖!

可以用来移动文件,相当于windows里的剪切命令

mv src dst

把文件或一个文件夹从左侧移动到右侧

移动整个目录

![[Pasted image 20240512215125.png]]

比如把test里的dir.bak移动到root目录里
![[Pasted image 20240512215322.png]]

移动完之后
![[Pasted image 20240512215336.png]]

当前root目录里就有dir.bak目录
![[Pasted image 20240512215405.png]]

而test目录里的就没有了

mv可以把整个目录全部移动过来

移动普通文件

![[Pasted image 20240512220403.png]]

输入

mv /root/test/file.txt .

将test目录下的file.txt移动到root目录下
![[Pasted image 20240512220812.png]]

移动并命名

将file.txt文件移动回去,并把名字重命名为f.txt
输入

mv file.txt ./test/f.txt

![[Pasted image 20240512221408.png]]

mv和cp一样
如果dst就是一个目录,就会把src放到这个目录里面
如果dst是一串路径,后面跟具体名字,会把src移动到dst的上级路径下,然后把名字改成指定的名字

对文件重命名

![[Pasted image 20240512224045.png]]

目前test目录下有dir和test两个目录
如果

mv dir test

dir后面跟一个存在的目录,mv的语义就是把dir整体移动到test目录里面
如果后面跟一个不存在的目录

mv dir rid

就是简单地将对应的目录进行重命名
在这里插入图片描述

同理

mv f.txt test

如果f.txt这个文件后面跟一个目录,就会把这个文件移动到这个目录里面
如果不存在

mv f.txt ttt

就会把文件名改成ttt
在这里插入图片描述

mv可以直接进行重命名,默认前面可以带路径

mv就是在绝对路径上操作

mv /root/test/ttt /root/test/yyy

mv就是把ttt剪切掉,改成yyy,其实就是move,只不过原始名字和目标名字不一样了,就是移动的时候顺便把名字改了
只不过刚好改名字在同一个目录下面又不冲突

06. which命令

which命令是查看指定命令在系统的什么路径下

命令的本质

命令的本质就是二进制或者其他脚本类的文件,就是可执行文件
![[Pasted image 20240513140518.png]]

test目录下的ttt文件,原本是txt文件,重命名成ttt.c,然后通过gcc编译,形成a.out可执行文件,在重命名成mycmd
这样输入mycmd就可以打印Hello Linux!
![[Pasted image 20240513140742.png]]

安装命令

学习的指令基本都是/usr/bin目录下的可执行程序
将自己写的命令拷贝到这个路径下,这个步骤就叫做安装

对应的可执行程序在bin目录里
![[Pasted image 20240513140824.png]]

所以可以将mycmd拷贝到bin目录下
![[Pasted image 20240513140928.png]]

这个时候执行cmd命令就不需要输入./
![[Pasted image 20240513141051.png]]

安装的本质就是把对应的可执行程序拷贝到系统能识别的路径下

卸载命令

输入

rm /usr/bin/mycmd

![[Pasted image 20240513141659.png]]

这样输入mycmd就会报错

07. alias指令

起别名
![[Pasted image 20240513144015.png]]

此时别名cho等价于ls -l

在命令行中起的别名,一旦xshell关闭,就自动删除了
如果需要别名每次都生效的话,需要改配置文件

08. cat指令

cat后跟的是文件名
后面跟什么文件,就会把这个文件打出来,打印的是文件的内容
![[Pasted image 20240513145318.png]]

输出行号打印文件
cat -n 文件名

后面加-n,默认打印的时候会带行号
![[Pasted image 20240513155301.png]]

对非空输出行号打印文件
cat -b 文件名

![[Pasted image 20240513155619.png]]

不输出多行空行打印文件
cat -s 文件名

![[Pasted image 20240513155508.png]]

逆向打印文件

使用tac来逆向打印文件
![[Pasted image 20240513155800.png]]

其他用法

cat直接回车
之后输什么,就打印什么
![[Pasted image 20240513160946.png]]

按Ctrl+c退出

cat从键盘文件读取什么,就像显示器文件写入什么
在这种场景当中,cat默认读取的时候,是从键盘文件中输入的

cat的用途

cat就是打印文件的内容
主要用来打印一些短小的文件
不想打开文件,就像单纯地把文件的内容显示出来
如简短的c++或配置文件

09. <符号

如何更换文件,不从键盘文件读入,从其他文件读入

cat < 文件名

<输入重定向
把本来应该从键盘文件中读入的内容,更改成为从普通文件中进行输入
称之为输入重定向
![[Pasted image 20240513161352.png]]

cat从该文件内部读入,读到什么,就在显示器上打印什么
照样也能把文件内容显示出来

10. echo指令

向一个文件中写入内容
可以用nano,打开文件在里面写
如果不想用nano编辑器,就像单纯地向文件当中写入

echo后面跟什么样的字符串,就会向显示器打印,显示什么字符串
![[Pasted image 20240513145422.png]]

echo写的时候会自动换行

11. >符号

可以通过echo来给文件写入信息
在后边加>

echo "Hello Linux!" > cho.txt

如果后边加的是不存在的文件名,>就会给新建一个文件
![[Pasted image 20240513145804.png]]

Linux下一切皆文件

向显示器打印,就相当于给显示器写入
读数据的时候是从键盘输入,键盘把数据同时给显示器一份,给程序一份
给显示器的过程就叫回显

显示器,读方法是空
键盘,写方法是空
大部分的硬件设备,都有读写方法,只不过有些方法可以为空
对于一个系统来说,对不同的硬件有不同的管理方法,肯定要作各种不同的工作

所有的设备,将来都可以以文件的形式挂靠到操作系统上,便于Linux作统一管理
减少Linux系统的编码维护成本

输出重定向

echo默认向显示器文件进行写入,但是一旦加了>,就改变了写入方向
变成了默认向文件内部作写入
本来应该是向显示器文件里写的东西,最终写入到了自定义的文件当中,就叫做输出重定向

输出重定向修改的是文件内容,文件属性会联动发生改变

输出重定向每一次写入的时候,不会保留上次的结果,会把上次的结果清掉,重新写新的内容
![[Pasted image 20240513154256.png]]

输出重定向写的时候,每次都会清空原始文件,然后再写入

新建空文件

可以通过在>后加文件名来新建文件
![[Pasted image 20240513153316.png]]

如果>重定向时,文件不存在,会新建文件
>左侧什么什么都没有,就意味着向zzz.txt文件里什么都不写
但是重定义这个符号需要被执行,最终>就新建一个文件

清空目标文件

>后跟目标文件

>zzz.txt

可以将文件内的内容清空
![[Pasted image 20240513154531.png]]

12. >>符号

追加重定向
向目标文件里不断在原始内容的基础之上,新增内容
![[Pasted image 20240513154857.png]]

三种重定向总结

<输入重定向,类比于c语言里的,r读取
>输出重定向,类比于c语言里的,w写入
>>追加重定向,类比于c语言里的,a追加

13. while语句

查看文件内容
可以通过这条语句,循环执行命令

i=0; while [ $i -le 10]; do xxx; let i++; done

i=0; while [ $i -le 10]; do echo "hello $i"; let i++; done

![[Pasted image 20240513170425.png]]

i=0; while [ $i -le 10]; do touch $i.txt; let i++; done

![[Pasted image 20240513170633.png]]

i=0; while [ $i -le 10]; do rm $i.txt; let i++; done

![[Pasted image 20240513170850.png]]

i=0; while [ $i -le 1000]; do echo "hello $i"; let i++; done > file.txt

![[Pasted image 20240513171132.png]]

用nano打开file.txt
![[Pasted image 20240513171216.png]]

制造了一个大文件

14. 其他查看文件相关命令

more命令

查看大文件
常用选项

  • -n 对输出的所有行编号
  • q 退出more
more 文件名

![[Pasted image 20240513171546.png]]

会在屏幕里显示内容,然后通过回车,逐行向下查看
只能下翻,没办法上翻

less指令
  • less 工具也是对文件或其它输出进行分页显示的工具,应该说是linux正统查看文件内容的工具,功能极其强大。
  • less 的用法比起 more 更加的有弹性。在 more 的时候,我们并没有办法向前面翻, 只能往后面看
  • 但若使用了 less 时,就可以使用 [pageup][pagedown] 等按键的功能来往前往后翻看文件,更容易用来查看一个文件的内容!
  • 除此之外,在 less 里头可以拥有更多的搜索功能,不止可以向下搜,也可以向上搜
    功能
    less与more类似,但使用less可以随意浏览文件,而more仅能向前移动,却不能向后移动,而且less在查看之前不会加载整个文件。
    选项
  • -i 忽略搜索时的大小写
  • -N 显示每行的行号
  • /字符串:向下搜索“字符串”的功能
  • ?字符串:向上搜索“字符串”的功能
  • n:重复前一个搜索(与 / 或 ? 有关)
  • N:反向重复前一个搜索(与 / 或 ? 有关)
  • q:quit
    输入
less file.txt

也是一屏打满
![[Pasted image 20240513172027.png]]

可以按回车,也可以按上下键

可以在命令行中输入

/行号

可以进行搜索
![[Pasted image 20240513172215.png]]

![[Pasted image 20240513172228.png]]

用途
在不打开文件时,查看文件源代码
可以查看简单的日志文件

head指令

功能
head 用来显示档案的开头至标准输出中,默认head命令打印其相应文件的开头10行。
选项

  • -n<行数> 显示的行数
    可以从头开始查看文件
head 文件名

可以在后面加-数字,指定显示的文件内容的行数
![[Pasted image 20240513172810.png]]

tail指令

tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不但刷新,使你看到最新的文件内容.
功能: 用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理。常用查看日志文件。
选项

  • -f 循环读取
  • -n<行数> 显示行数
    默认显示文件的后十行
    ![[Pasted image 20240513172934.png]]

后面也可以限定行数
![[Pasted image 20240513173028.png]]

查看文件任意部分

如果想提取500到510行的内容
分两步

  1. 先提取头部1到510行的内容
  2. 提取尾部500到510行的内容
    需要将第一步的输出结果,作为第二步的输入
head -510 file.txt > temp.txt

![[Pasted image 20240513173941.png]]

用less查看

tail -10 temp.txt

![[Pasted image 20240513174044.png]]

15. |符号

命令行管道
管道里流动的是上一个命令所对应的输入数据,把数据交给管道
管道再把数据流动到下一个指令,作为输入
将多条指令联系到一起

将head -510 file.txt的输出作为tail -10的输入

head -510 file.txt | tail -10

![[Pasted image 20240513174425.png]]

局部逆置
![[Pasted image 20240513174938.png]]

再查看前三行
![[Pasted image 20240513175021.png]]

可以通过管道不断对数据进行多指令连接,完成简单的流水线式的处理

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 中,使用 C 语言模拟 shell 命令可以通过调用系统函数实现。以下是一个简单的例子,演示了如何使用 C 语言实现重定向管道通信。 首先,我们需要包含一些头文件: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> ``` 接下来,我们可以定义一些常量,例如: ```c #define MAX_ARGS 10 #define MAX_BUFFER 1024 ``` 然后,我们可以定义一个函数来解析用户输入的命令,并将其分解为单个参数。以下是一个简单的实现: ```c void parse_command(char *command, char **args, int *redirect_input, int *redirect_output) { int arg_count = 0; char *token; char *rest = command; while ((token = strtok_r(rest, " ", &rest))) { if (*token == '<') { *redirect_input = open(token + 1, O_RDONLY); } else if (*token == '>') { *redirect_output = open(token + 1, O_WRONLY | O_CREAT | O_TRUNC, 0644); } else { args[arg_count++] = token; } } args[arg_count] = NULL; } ``` 此函数通过使用 `strtok_r()` 函数将命令分解为参数。如果命令包含输入重定向符 `<`,则将 `redirect_input` 指针设置为打开输入文件的文件描述符。如果命令包含输出重定向符 `>`,则将 `redirect_output` 指针设置为打开输出文件的文件描述符。在解析完成后,参数将存储在 `args` 数组中。 接下来,我们可以定义一个函数来处理管道通信。以下是一个简单的实现: ```c void pipe_commands(char **commands) { int fd[2]; pid_t pid1, pid2; char *args1[MAX_ARGS], *args2[MAX_ARGS]; if (pipe(fd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } parse_command(commands[0], args1, NULL, &fd[1]); parse_command(commands[1], args2, &fd[0], NULL); pid1 = fork(); if (pid1 == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid1 == 0) { close(fd[0]); dup2(fd[1], STDOUT_FILENO); close(fd[1]); execvp(args1[0], args1); } else { pid2 = fork(); if (pid2 == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid2 == 0) { close(fd[1]); dup2(fd[0], STDIN_FILENO); close(fd[0]); execvp(args2[0], args2); } else { close(fd[0]); close(fd[1]); wait(NULL); wait(NULL); } } } ``` 此函数创建一个管道,然后使用 `parse_command()` 函数解析两个命令,并将其分别存储在 `args1` 和 `args2` 数组中。接下来,它调用 `fork()` 函数创建两个子进程,其中一个子进程执行第一个命令,另一个子进程执行第二个命令。使用 `dup2()` 函数将子进程的标准输出或标准输入连接到管道的适当端口。最后,主进程等待两个子进程完成。 最后,我们可以定义一个主函数来使用这些函数来执行用户输入的命令。以下是一个简单的实现: ```c int main() { char buffer[MAX_BUFFER]; char *commands[2]; int redirect_input = 0, redirect_output = 0; while (1) { printf("$ "); if (fgets(buffer, MAX_BUFFER, stdin) == NULL) break; commands[0] = strtok(buffer, "|"); if ((commands[1] = strtok(NULL, "\n")) != NULL) { pipe_commands(commands); } else { parse_command(commands[0], commands, &redirect_input, &redirect_output); pid_t pid = fork(); if (pid == -1) { perror("fork"); exit(EXIT_FAILURE); } else if (pid == 0) { if (redirect_input) { dup2(redirect_input, STDIN_FILENO); close(redirect_input); } if (redirect_output) { dup2(redirect_output, STDOUT_FILENO); close(redirect_output); } execvp(commands[0], commands); } else { wait(NULL); } } } return 0; } ``` 此函数使用 `fgets()` 函数从标准输入读取用户输入的命令。如果命令包含管道符 `|`,则使用 `strtok()` 函数将命令分解为两个命令,并使用 `pipe_commands()` 函数执行它们之间的管道通信。否则,就使用 `parse_command()` 函数解析命令,并使用 `fork()` 函数创建子进程来执行命令。在子进程中,使用 `dup2()` 函数将标准输入或标准输出重定向到适当的文件描述符。最后,主进程使用 `wait()` 函数等待子进程完成。 这就是使用 C 语言模拟 shell 命令的基本方法。请注意,此实现仅用于演示目的,并且可能需要进行更改以处理更多情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值