Shell编程
Shell基础
- Shell简述
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Shell与内核及用户间的关系:硬件->Kernel->Shell->用户 - Bash与Shell
命令解释器:Shell
Shell严格上可以分为两种:GUI图形界面Shell和CLI命令行Shell。
Shell是指CLI命令行Shell,作用:解释用户输入的命令。
命令处理器:Bash(终端)
Bash是众多CLI命令行Shell中的一种实现,能够提供命令解释的功能。
注释:用户可通过“ls /bin/*sh”命令查看系统中安装的shell。 - Shell脚本
Linux系统中的所有可执行文件都可以在shell中执行。
Linux系统中的可执行文件可以分为五类:
① Linux命令:用来使系统执行某种操作的指令,存放在/bin和/sbin目录下。
② 内置命令:存放于Shell内部的命令的解释程序,是一些常用的命令。
可以使用“type 命令名”的方式来查看某个命令是否为内置命令。
③ 实用程序:存放于/usr/bin、/usr/sbin、/usr/local/bin等目录下的程序,如ls、which等。
④ 用户程序:由用户编写的,经过编译后可执行的文件。
⑤ Shell脚本:使用Shell语言编写的批处理文件。
Shell对命令的解释过程如图所示:
Shell脚本(Shell Script)是一种解释型语言。
Shell脚本中的主要内容就是各种命令,每个命令都可以在Shell中单独执行,
经过一些操作符的连接、判断、循环等操作形成了一门新的编程语言。#!/bin/bash #显示"Hellow World!" echo "Hello World!"
#!
作用:指定该脚本的解释器,即脚本的运行环境。
/bin/bash
作用:解释器的绝对路径。
终端输入./文件名.sh
允许。
注释:新建的文件没有可执行权限,需要执行chmod +x 文件名.sh
赋予权限。
变量
- 变量声明
变量名=变量值
将变量名赋值给变量值字符串,此时变量名的数据类型时字符串类型。
例如:x=tets
declare命令
语法规则:declare 数据类型 变量名
作用:指定变量的类型(typeset命令作用一样)。
常用的数据类型:
-i
定义一个整数类型的变量。
-a
定义一个数组类型的变量。
-f
定义一个函数类型的变量。
-r
定义一个只读变量。
readonly命令
语法规则:readonly 变量名=赋值
作用:只读变量,不可修改删除,程序执行完成或exit退出即结束。
unset命令
语法规则:unset 变量名
作用:销毁(删除)变量。 - 变量赋值
变量赋值通常有两种方式:
①=
操作符赋值
②read
命令进行赋值
等于号操作符赋值
例如:x=5
打印:echo $x
注意:之间不能有空格。
read命令
语法规则:read 变量名
作用:终端输入。
-e
在一个交互式Shell中使用Readline获取行。
-i
使用text文本作为Readline的初始文字。
-n
后跟一个数字,定义输入文本的长度,很实用。
-N
在准确读取了n个字符后返回,除非遇到文件结束或者都超时,任何的分隔符都被忽略。
-m
读取n个字符之后返回,而不是等到读取换行符。
-M
在准确读取了n个字符之后返回,除非遇到文件结束或者读超时,任何分隔符都被忽略。
-p
后面跟提示信息,即在输入前打印提示信息。
-r
不允许反斜杠转义任何字符。
-s
不显示终端的任何输入。
-t
后面跟秒数,定义输入字符的等待时间。
-d
后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志。
-a
后跟一个变量,该变量会被认为是一个数组,然后给其赋值,默认是以空格为分隔符。 - 变量的引用
变量引用通常有四种方式:
①$变量名
最常用的引用方式。
②${变量名}
通常用在变量之后还有其他字符串的情况。
③"$变量名"
通常用在变量值含有空格的情况,引号不能省略。
④"${变量名}"
通常用在变量值含有空格的情况,引号不能省略。 - 变量分类
Shell变量大体可分为三大类:
① 内部变量:
内部变量通常用来进行系统参数的获取,
比如读取Shell 脚本文件的名称或者读取上一次命令执行的返回值等。
② 环境变量(永久变量):
每个操作系统中都会有一些默认的变量,被称为环境变量,每个用户可以根据其要求对环境变量进行更改。
此类变量不仅可以作用于单个脚本,还可用于创建该变量的Shell以及从该Shell派生的子Shell或进程中。
③ 参数变量(临时变量):
参数变量通常是指一些用户在代码编写过程中自定义的一些变量,
这些变量能够保存Shell Script运行中的一些临时数据,这些数据是可以改变的。
export关键字
语法格式:export 变量名=值
作用:设定或创建环境变量。
注释:若要将一个本地变量更改为环境变量,使用export 变量名
。
位置变量
定义:执行脚本时传入脚本中,对应位置的变量,类似函数的参数。
引用方法为"$"加上参数的位置,如:$0、$1、$2,其中$0
比较特殊,表示获取脚本的名称。
其余依次表示传入脚本中第一个参数、第二个参数等。
#
较特殊,表示传递到脚本的参数个数(脚本名hello.sh)#!/bin/bash echo hello world echo "number of vars:"$# echo "name of shellsctip:"$0 echo "first var:"$1 echo "secord var:"$2 echo "third var:"$3
注释:abc即为传入的参数。
shift:可以移动位置变量对应的参数,shift每执行一次,参数序列顺序左移一个位置,移出去的参数不可再用。
注释:shift后面开始执行,每一个shift后面依次左移一个。#!/bin/bash echo hello world echo "number of vars:"$# echo "name of shellsctip:"$0 shift echo "first var:"$1 echo "secord var:"$2 echo "third var:"$3
- Shell中的引导
在Shell中,几乎所有的字符都会被认为是字符串,所以引号的使用也与大多数编程语言不同,
Shell中常见的有三种引号,使用方法各不相同。
单引号通常有两种用方法:
① 当字符串中含有空格时,需要使用单引号进行引用。
② 直接原样输出,并不会将引用的变量值输出。
双引号通常用两种使用方法:
① 当字符串中含有空格时,需要使用双引号进行引用。
② 当想输出变量值,而不是变量名时。
反引号在其他编程语言中较少见,也有两种用法:
① 为命令起别名。
② 将后续命令的结果返回给前序命令。
示例-命令替换
结果都一样,如下:<!--反引号--> cmd=`ls` echo $cmd <!--$()--> files=$(ls) echo $files
注释:使用反引号进行命令替换的方法,替换之后,再次输出变量值时,实际上是输出对应命令的执行结果;
这种方法用途非常广泛,不仅限于命令的替换,也可以实现命令参数的传递。 - 变量的间接引用
Shell支持变量的间接引用,即某个变量的值是另外一个变量的变量名情况,Shell支持间接引用使用的是“!”操作符。yuts@yuts-virtual-machine:~$ x=tedu <!--将变量作为值赋给另一个变量--> yuts@yuts-virtual-machine:~$ y=x <!--直接输出y变量的值,认为x是字符串,所以输出“x”--> yuts@yuts-virtual-machine:~$ echo $y x <!--使用!操作符,间接输出,则输出x变量的值--> yuts@yuts-virtual-machine:~$ echo ${!y} tedu <!--单独使用!操作符,输出y变量的赋值语句--> yuts@yuts-virtual-machine:~$ !y y=x yuts@yuts-virtual-machine:~$
- 命令别名
alias命令
语法格式:alias newname=command
作用:对于较长的命令记忆比较困难,可以使用alias命令起别名。
示例:重新命令名:alias lstest="ls|grep test"
unalias命令
语法格式:unalias 别名
作用:将指令进行替换;可以使用unalias命令销毁别名。
运算符
-
算术运算符
常用的运算符:运算符 作用 ++、– 自增、自减运算符,能够做到变量自身加1、减1 +、- 加、减运算符,能够计算两个数的加、减运算,如果该操作符前并没有数字,则该符号代表正、负号,标识数字正、负属性 * 计算两个数字相乘 / 计算两个数字相除,并输出商 % 计算两个数字相除,并输出余 例如:
echo $((x++))
-
位运算符
常用的运算符:运算符 作用 ~ 按位取反 <<、>> 左移、右移,一般用在二进制的操作 & 按位与 ^ 按位异或 I 按位或 补充:
① 原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示数值。
② 反码的表示方法是:
正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。
③ 补码的表示方法是:
正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
按位取反计算方法:
正数:补码按位取反,减一,取反码。
负数:补码按位取反。 -
逻辑运算符
常用逻辑运算符:操作符 名称 意义 -a 与 该运算符两侧的条件都为真时,结果为真 -o 或 该运算符两侧的条件其中有一个为真时,结果为真 ! 非 该运算符为单目运算符,只需要一个条件即可,当给定的条件为真是,结果为假,当给定的条件为假时,结果为真 && 与 当左侧的表达式为真时,继续判断右侧表达式,右侧表达式同为真时,结果为真;左侧表达式为假时,不再判断右侧表达式,结果为假 II 或 当左侧表达式为假时,继续判断右侧表达式,右侧表达式同为假时,结果为假,右侧表达式为真时,结果为真;当左侧表达式为真时,不再判断右侧表达式,结果为真 逻辑与示例:
test -z "" -a -n "abc";echo $?
结果为0
test -z "a" -a -n "abc";echo $?
结果为1
-z
如果字符串为空,则为真。
-n
如果字符串不为空,则为真。
;
两条命令间的连接符号。 -
三元运算符
语法格式:表达式1?表达式2:表达式3
解析:当表达式1为真,则输出表达式2的值;反之当表达式1为假,则输出表达式3的值。 -
赋值运算符
语法格式:变量=表达式
解析:赋值运算符是各类编程语言中最重要、最基础的运算符,其与数学中的等号不同,赋值表达式中,左侧为变量名,右侧为表达式。 -
运算符优先级
引入:当一个表达式中出现多个运算符时,首先会按照每个运算符的优先级进行运算,
即先对优先级高的运算符进行运算,再计算优先级低的运算符进行计算。
常见运算符的优先级及结合方向如右表所示:
注意:在多个运算符同时使用时,可以通过括号改变优先级。
例如:y=$(((2*3+3)*5));echo $y
-
let命令、其他表达式
let命令
语法格式:let 表达式
作用:let命令能够计算一个算数表达式,并将结果赋给指定的变量。
其他表达式
语法格式:$((表达式)) $[表达式]
上述两种表达式,作用于let命令相同,也是进行算数运算,这些语法更常用,也更方便。
示例:y=$((2*3))
与let y=2*3
效果一样。
条件测试
-
条件测试
在各类编程语言中,条件判断是一项非常重要的功能,例如可以通过条件判断来决定程序的走向、循环次数等。
语法规则:test condition [condition] [[ condition ]]
a=2 b=2 num1="abc" num2="abc100" if test $[a]-eq$[b] <!--test测试命令--> then echo "a等于b" else echo "a不等于b" fi if test $num1=$num2 then echo "两字符串相同" else echo "两字符串不相同" fi
-
文件测试
作用:主要是判断文件是否符合指定的文件属性或文件是否存在。
判断文件是否为块设备:<!--查看/dev/sda文件的属性--> <!--b代表该文件时块文件--> ls -b /dev/sda <!--测试该文件是否为块文件,显示结果为真0--> [ -b /dev/sda ];echo $?
-
字符串测试
操作符 意义 < 按ASCII码顺序,前面的字符串小于后面的字符串则为真 > 按ASCII码顺序,前面的字符串大于后面的字符串则为真 == 字符串完全相同为真 = 字符串相等为真 =~ 前面的字符串中包含后面的字符串时为真 != 字符串不相等为真 -z 字符串为空则为真 -n 字符串非空为真 示例:
[[ "abc"=="abc" ]];echo $?
注意:以上左右操作符,在使用时,必须两侧都有空格才可以,否则shell会将其中的操作符当做普通字符进行处理。 -
整数测试
常用整数测试操作符:操作符 意义 -eq equal to,两个数相等为真 -ge greater than or equal to,前者大于等于后者为真 -gt greater than,前者大于后者为真 -le less than or equal to,前者小于等于后者为真 -lt less than,前者小于后者为真 -ne no equal,两者不相等为真
分支语句
- if语句
语法格式:
示例:if [ 条件测试 ] then 条件测试为真时执行该语句 elif [ 条件测试 ] then 条件测试为真时执行该语句 else 上述条件测试为假时执行该语句 fi 注释:使用;把then后接在if [ 条件测试 ]也可以。
#!/bin/bash if [ -e ~/.bashrc] then echo file exists else echo file is not exists fi
- case语句
语法格式:类似C语言中switch…case…
示例:case "变量值" in "var1") 语句 ;; "var2") 语句 ;; "var3") 语句 ;; *) 语句 ;; esac
if与case区别:当判断条件过得时,case语句要比elif简洁。#!/bin/bash read name case "$name" in "tedu") echo hi tedu ;; "os") echo hi os ;; *) echo this is default line ;; esac
循环语句
- for循环
语法格式:
遍历数组:<!--var循环变量,list数组变量--> for var in list do 循环语句 done
#!/bin/bash array=(1 2 3 4 5) for num in ${array[@]} <!--遍历列表--> do echo $num done
- while循环
语法格式:
示例:while 表达式 do 循环语句 done
注释:while与for一样,表达式为条件测试,当表达式的值为真时,循环语句便会执行,否则循环将退出。#!/bin/bash array=(1 2 3 4 5) <!--定义一个列表--> length=${#array[@] <!--获取列表长度并赋值给length变量--> i=0 <!--定义while循环中初始值i--> while (($i<$length)) <!--判断条件是否满足while循环,真循环,假退出--> do echo ${array[i]} <!--输出索引i所对应的列表值--> let "i++" <!--变量i的值加1--> done
- until循环
语法格式:
示例:until 表达式 do 循环语句 done
注意:until是在条件测试为假时执行循环语句,直到条件测试为真时退出。#!/bin/bash array=(1 2 3 4 5) length=${#array[@] i=0 until (($i<$length)) <!--判断条件是否满足until循环,假循环,真退出--> do echo ${array[i]} let "i++" done
- select循环
select循环结构是Shell中比较特殊的一种循环结构,
前面的循环结构中,大多有一个数组来保存各个元素,有时也不需要数组,
而select循环结构中数组和变量是必须的,select循环是一个可以和用户进行交互的循环结构,shell中非常实用。
语法格式:
注意:select循环结构是死循环,因此必须使用break、exit或ctrl+c组合键等方法退出脚本。select var in list do 循环语句 done
示例:
输出结果:#!/bin/bash echo "What is your favourite OS?" <!--选项,这些选项每一项都会在前面加上序号输出;之后通过输入选项前的数字进行选择,并将选择结果赋给var变量--> select var in "Linux" "Gnu Hurd" "Free BSD" "Other";do break; done echo "You selected $var"
yuts@yuts-virtual-machine:~$ ./select.sh What is your favourite OS? 1) Linux 2) Gnu Hurd 3) Free BSD 4) Other #? 1 You selected Linux
- continue与break语句
continue语句
功能:终止本次循环,终止后脚本会跳回到循环的起始位置,
继续执行剩下的循环,所以continue并不能彻底终止循环,
而只是跳过一次不满足特定条件的循环,其他循环并不会受到影响。
break语句
功能:跳出循环,在循环执行过程中,执行break指令,
则循环会直接退出,而不论后续还有多少次没有执。
数组
- 定义数组
数组简介
对于任何一种编程语言来说,数组都是一种非常重要的数据结构。
数组就是一组有序的列表,其中可以存储各种类型的数据,
同时每个数据又都有其唯一的标号,通过标号能够快速的更改或读取指定位置的数据值。
六种常用的定义数组方式
① 直接定义
a1=(1 2 3 4 5)
② 先用declare命令声明数组变量,之后再进行初始化
declare -a a2
a2=("a" "b" "c" "d" "e")
③ 每行一个元素进行数组初始化
a3=(1
2
3
…
)
④ 将包含有空格的字符串直接转化为数组
data="t e d u"
a4=($data)
⑤ 每个元素单独进行初始化
a5[0]=1
a5[1]=2
a5[2]=3
……
⑥ 使用索引初始化每个索引位置的值
a6=([0]=1 [1]=2 [2]=3 [3]=4 [4]=5)
销毁数组元素:unset a1[4]
销毁数组:unset a1
- 获取数组长度
Shell中提供#
操作符来获取数组的长度,可以使用两种方法进行获取。
语法格式:${#array[@]
或${#array[*]}
注意:#
操作符的作用就是获取参数的长度,不仅可以获取数组的长度,对于变量也可以使用该操作符进行获取长度。
示例:
echo ${#a2[@]}
输出数组长度
echo ${#x}
输出字符长度(字符数量) - 数组切片
数组中常常包含有同一类型的许多数值,而在具体到程序中某个功能的时候,
往往不需要用到数组的全部元素,此时需要将用到的部分取出,形成一个新的数组,也就是数组的切片。
语法格式:array1=${array[@]:m:n}
或array1=${array[*]:m:n}
array:原数组。
array1:新建数组,该操作将原数组的内容切片后赋值给新建的数组。
m:切片的起始位置。
n:需要提取的元素的个数。yuts@yuts-virtual-machine:~$ array=(a b c d e) <!--定义数组--> yuts@yuts-virtual-machine:~$ array1=${array[*]:2:2} <!--取原数组中第2位开始,合计2个元素赋值给--> yuts@yuts-virtual-machine:~$ echo ${array1[*]} c d yuts@yuts-virtual-machine:~$ array2=${array[*]:2} <!--取原数组第2位开始,至最后的所有元素赋值--> yuts@yuts-virtual-machine:~$ echo ${array2[*]} c d e yuts@yuts-virtual-machine:~$ array3=${array[*]::2} <!--取原数组的第0位开始,合计2个元素--> yuts@yuts-virtual-machine:~$ echo ${array3[*]} a b yuts@yuts-virtual-machine:~$ array4=${array[*]:(-3):2} <!--取原数组倒数第3位开始,取之后合计2个元素--> yuts@yuts-virtual-machine:~$ echo ${array4[*]} c d
- 数组替换
通常,在数组中修改元素值,需要重新对该数组按照索引进行赋值才可以,
而在Shell中,提供了一种简单的方法来替换数组中的元素。
语法格式:${#array[@]/from/to
或${#array[*]/from/}
array:需要替换的数组名称。
from:数组中需要被替换的旧字符串。
to:被替换的新的字符串,可以省略。yuts@yuts-virtual-machine:~$ array=("ios" "android" "windows" "linux") <!--初始化数组为各类操作系统名称--> yuts@yuts-virtual-machine:~$ echo ${array[@]/i/I} <!--替换i为I--> Ios andrord wrndows lrnux yuts@yuts-virtual-machine:~$ echo ${array[@]/i/} <!--替换i为空,即删除i--> os androd wndows lnux yuts@yuts-virtual-machine:~$ echo ${array[@]/ios/iOS} <!--替换ios为iOS--> iOS android windows linux
- 关联数组
除了常见的下标索引形式的数组,Shell中还有一种被称为关联数组的数组形式,
借助散列技术,使用字符串作为索引值,而不是使用的数字作为索引。
语法格式:ass array=([index]=vall [index]=val2)
普通数组通常使用数字作为索引,而关联数组中的index可以使用字符串作为索引,
通过索引与值的一一对应,使索引与值关联起来,构成关联数组。<!--定义一个关联数组--> yuts@yuts-virtual-machine:~$ declare -A assarray=([tedu]="hello tedu" [world]="hello world") yuts@yuts-virtual-machine:~$ echo ${assarray[tedu]} <!--输出索引tedu对应的值--> hello tedu yuts@yuts-virtual-machine:~$ echo ${assarray[world]} <!--输出索引world对应的值--> hello world yuts@yuts-virtual-machine:~$ echo ${assarray[@]} hello tedu hello world yuts@yuts-virtual-machine:~$ assarray["os"]="hello os" <!--使用赋值语句为单个数组索引赋值--> yuts@yuts-virtual-machine:~$ echo ${assarray[os]} hello os yuts@yuts-virtual-machine:~$ echo ${!assarray[@]} <!--输出关联数组中索引值--> tedu world os yuts@yuts-virtual-machine:~$ echo ${assarray[@]} <!--输出关联数组中元素值--> hello tedu hello world hello os
函数
-
函数定义
当程序实现的功能比较复杂时,通常我们可以将一部分程序提取出来,形成一个模块,
通过模块的方式对程序进行简化,这种模块被称为函数,shell也支持函数的创建及调用。
语法格式:function 函数名() { 函数体 }
function关键词:代表后面的内容是函数。
函数名:在程序中函数名通常是唯一的,调用时,直接引用函数名即可。
函数体:多条语句的集合,函数主要功能是由函数体实现。
示例:#!/bin/bash function func1 () <!--函数名--> { echo first function <!--函数体--> } func1 <!--函数调用-->
-
函数参数
函数参数是函数调用时,用以传递给函数的一些数据,Shell中函数可以接受多个参数。
除了传递进来的参数外,每个函数中还都包含了一些内部参数,常用获取内部参数使用的。
常见的内部参数符号如下所示:符号 意义 # 传递到脚本的参数个数 * 以一个单字符串显示所有向脚本传递的参数 $ 脚本运行是的档期那进程ID号 ! 后台运行的最后一个进程ID号 @ 与*相同,但是使用时加引号,并在引号中返回每个参数 _ 显示Shell使用的当前选项,与set命令功能相同 ? 显示最后命令的退出状态 示例:
#!/bin/bash function func1() { echo scrip name:$0 <!--0号变量指脚本名称--> echo first function:$0 <!--1号变量指函数调用时传递的变量值--> echo first function } func1 tedu <!--函数调用时传递的变量-->
-
函数返回值
返回值是函数执行后需要返回的一些信息。在Shell编程中,每个函数都会有返回值,
通常,如果一个函数没有自定义返回值,则该函数会以最后一条指令执行结果作为返回值返回。
如果用户希望自定义返回值,可以在函数的最后添加“return n”,其中n的取值为0~255。
示例:#!/bin/bash function func1() { echo first function <!--如果没有指定返回值返回值为最后一条命令的返回值--> } function func2() { echo second function <!--如果指定了返回值返回值就是指定的值--> renturn 3 } func1 echo 第一个函数的返回值是:$? func2 echo 第二个函数的返回值是:$?
文本处理
-
格式化输出
格式化输出能够对把输出的内容根据指定的格式输出,自动进行对齐、换行等操作。
printf指令
常用的格式化字符:格式化字符 意义 \a 输出警告音 \b 退格 \f 清楚屏幕 \n 输出新行 \r 代替enter键 \t 水平tab键 \v 垂直tab键 \xNN 转换数字为字符 %ns 输出n个字符 %ni 输出n个整数字符 %N.nf 输出小数,其中N为整数部分位数,n为小数位数 -
sed命令
sed是一个很好的文本处理工具,其本身是一个管道命令,
主要是以行为单位进行文本文档的处理,可以将数据行进行替换、删除、新增、选取等特定工作。
命令格式:sed [选项] 文件名
示例:sed '1d' case.sh|head -n 3
sed常用选项及功能如下所示:
-n
使用安静模式。
-e
直接在命令列模式上进行编辑。
-f
将sed命令输出到文件中,通过执行该文件执行对应的sed命令。
-r
执行正则表达式的语法。
-i
直接修改读取的文件内容,而不是输出到终端。
-a
将增行,a的后面可以是字符串。
-c
取代行,c的后面可以是字符串。
-d
删除行,通常后面不接参数,直接删除对应行。
-p
列印,将某个选择的数据打印出,通常与-n选项一起运行。
-s
替换,直接或通过正则表达式进行替换。 -
awk命令
作为一款文本处理工具,awk被设计用于数据流,其不仅能够对行进行操作,还可以对列进行操作。
awk命令有许多内建的功能,比如数组、函数等,具有很大的灵活性。
语法格式:awk 'BEGIN { command } { command 1 } END{ command 2 }' file
command是脚本开始执行时执行的命令。
command_1为脚本执行过程中执行的命令。
command_2为脚本执行结束时执行的命令。
File是需要被处理的文件名称。
示例:使用awk输出/etc/passwd的账户人数:
awk '{count++;print $0;} END{print "user count is", count}' /etc/passwd
-
文本内容比较
diff命令能够对两个文件进行详细的对比,并将差异结果进行重点标记,输出到文件中。
输出到的文件成为被修补文件(patch file),其中包含了修改过的、添加、删除的行及行号,
用户可以通过修补文件对源文件进行更改。
语法格式:diff ver1 ver2
ver1和ver2是要对比的两个文件,对比结果会输出到终端中,也可以采用重定向的方式将输出保存到任意位置。
示例:使用diff命令查看文件不同:<!--使用重定向创建两个文件,内容为当前目录的文件及属性--> yuts@yuts-virtual-machine:~$ ls -l > ver1 yuts@yuts-virtual-machine:~$ ls -l > ver2 <!--使用diff命令查看文件内容不同的地方--> yuts@yuts-virtual-machine:~$ diff ver1 ver2 <!--第1个2324代表第一个文件中的第2324行;c代表change,即改变;第2个2324代表第二个文件的第2324行--> 23,24c23,24 < -rw-rw-r-- 1 yuts yuts 0 12月 5 20:27 ver1 < -rw-rw-r-- 1 yuts yuts 1477 12月 5 20:26 ver2 <!--上边是第一个文件,下边是第二个文件--> --- > -rw-rw-r-- 1 yuts yuts 1477 12月 5 20:27 ver1 > -rw-rw-r-- 1 yuts yuts 0 12月 5 20:27 ver2 yuts@yuts-virtual-machine:~$ <!--<符号代表第一个文件,>符号代表第二个文件-->