Linux入门(四)-shell脚本

shell简介

什么是shell脚本

       我们已经能够熟练的在终端中输入命令来完成一些常用的操作,但是我们都是一条一条输入命令。将多个Shell 命令按照一定的格式放到一个文本中,那么这个文本就叫做 Shell 脚本!shell脚本类似Windows的批处理文件,shell脚本就是将连续执行的命令写成一个文件。shell脚本提供数组、循环、条件判断的等功能。shell脚本一般是Linux运维或者系统管理员要掌握的,作为嵌入式开发人员,只需要掌握shell脚本最基础的部分即可。

        严格意义上来讲,Shell 是一个应用程序,它负责接收用户输入的命令,然后根据命令做出相应的动作, Shell 负责将应用层或者用户输入的命令传递给系统内核,由操作系统内核来完成相应的工作,然后将结果反馈给应用层或者用户。

shell四种运行方式(启动方式)

shell是一个应用程序,它的一端连接着Linux内核,另一端连接着用户。Shell 是用户和 Linux 系统沟通的桥梁,我们都是通过 Shell 来管理 Linux 系统。

我们可以直接使用 Shell,也可以输入用户名和密码后再使用 Shell;第一种叫做非登录式,第二种叫做登录式。我们可以在 Shell 中一个个地输入命令并及时查看它们的输出结果,整个过程都在跟 Shell 不停地互动,这叫做交互式。我们也可以运行一个 shell脚本文件,让所有命令批量化、一次性地执行,这叫做非交互式
总的来说,Shell 一共有四种运行方式:

  • 交互式的登录 Shell;
  • 交互式的非登录 Shell;
  • 非交互式的登录 Shell;
  • 非交互式的非登录 Shell。

shell基本操作

一、shell脚本写法

shell脚本是个纯文本文件,命令从上而下,一行一行的开始执行。shell脚本扩展名为.sh。使用vi xxx.sh进入编辑shell脚本文件。shell脚本第一行一定要为:

#!/bin/bash    // 表示使用bash。

二、shell脚本语法

交互式shell脚本

打印输出用echo命令;输入用read命令。

  

Linux read命令用于从标准输入读取数值。read 内部命令被用来从标准输入读取单行数据。这个命令可以用来读取键盘输入,当使用重定向的时候,可以读取文件中的一行数据。

参数说明:

read -a 后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符。

read -d 后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志。

read -p 后面跟提示信息,即在输入前打印提示信息。

read -e 在输入的时候可以使用命令补全功能。

read -n 后跟一个数字,定义输入文本的长度,很实用。

read -r 屏蔽\,如果没有该选项,则\作为一个转义字符,有的话 \就是个正常的字符了。

read -s 安静模式,在输入字符时不再屏幕上显示,例如login时输入密码。

read -t 后面跟秒数,定义输入字符的等待时间。

-p 参数,允许在 read 命令行中直接指定一个提示。

shell脚本的数值计算

shell仅支持整形,数值计算使用$((表达式))。(如下示例第五行,计算和)

total写的时候=左右两边不能有“空格”。否则会提示“total命令未找到”。

Shell  test命令

Shell中的 test 命令用于检查某个条件是否成立,查看文件是否存在、权限等信息,可以进行数值,字符,文件三方面的测试。

test -e 文件名如果文件存在则为真
test -r 文件名如果文件存在且可读则为真
test -w 文件名如果文件存在且可写则为真
test -x 文件名如果文件存在且可执行则为真
test -s 文件名如果文件存在且至少有一个字符则为真
test -d 文件名如果文件存在且为目录则为真
test -f 文件名如果文件存在且为普通文件则为真
test -c 文件名如果文件存在且为字符型特殊文件则为真
test -b 文件名如果文件存在且为块特殊文件则为真
&&和||命令(在shell脚本下与C语言中意思不同):

cmd1 && cmd2:当cmd1执行完并且正确,那么cmd2开始执行,如果cmd1执行完毕错误,那么cmd2不执行。

cmd1 || cmd2:当cmd1执行完毕并正确,那么cmd2不执行,反之cmd2执行。

管道命令:cmd1 | cmd2,cmd1的输出作为cmd2的输入,cmd1不能输出错误信息。

判断文件是否存在示例:

 

 判断字符串是否相等示例:

中括号[ ]判断符

[  ] 里面用 == 或 !=,[ ]相比test命令使用起来较为方便一些。

#!/bin/bash
read -p "input a:" a
read -p "input b:" b

[ $a -eq $b ] || echo "a!=b"     判断变量a与b是否相等,不相等的话打印输出a!=b
[ -z $a ] || echo "${a}"         判断输入的字符串是否为空
[ -d $a ] && echo "${a}"         判断输入的文件名的文件是否存在,且是否为目录文件
Shell脚本的默认变量

$0~$n,表示shell脚本的参数,包括shell脚本命令本身,shlle脚本命令本身为$0。

$#:#表示最后一个参数的标号。

$@:表$1、$2、$3......(所有参数的内容)

shell脚本条件判断、函数和循环

一、shell脚本条件判断

shell脚本支持条件判断,虽然可以通过&&和||来实现简单的条件判断,但是稍微复杂一点的场景就不适合了。

1.shell脚本提供了if then条件判断语句结构:
if command|condition;    //条件判断
then
    commands      //判断成立要做的事情
fi       //退出if判断
2.还有if then else 语句结构:
if command|condition;    //条件判断
then
	commands     //条件判断成立要做的事情
else
	commands     //条件判断不成立要做的事情
fi
3.if  then...elif  then....    ....else...fi多层嵌套结构:
 
if command|condition;    //条件判断
then
	commands
elif command|condition;    //条件判断
then
	commands
elif command|condition;    //条件判断
then
	commands
else
	commands
fi
4.最后还有case语句(类似C语言的switch-case结构,变量和下面值1,2,...,n匹配)
case "$变量" in
    值1)        //半个括号是规则
        指令1...
    ;;         //表示该程序块结束!!
    值2)
        指令2...
    ;;
    *)        //*代表其它所有的
        指令3...
esac        //反写case,代表case语句结束

二、shell脚本函数

shell脚本也支持函数,函数写法如下:

function  函数名(){
       //函数代码段
}

定义两个函数:help和close,用case语句判断输入的是 “-h” 还是 “-c” 。调用函数时候不用像C语言中help( )这样子,直接“help”即可。

shell脚本函数传参:并不是在括号里面写传入的参数。

 

三、shell循环

shell脚本也支持循环

1.首先,while do done,表示当条件成立的时候就一直循环,直到条件不成立。写法如下:
while [ 条件 ]        //判断条件(判断式)
do                //循环开始
    执行命令       //要循环的代码段部分
done               //结束循环
2.还有另外一种,until do done,表示条件不成立时循环,条件成立后就不循环了,写法如下:
until 条件          //判断式
do
    执行命令        //要循环的代码部分
done
3.for循环,使用for循环可以知道有循环次数。

for循环的运作方式:是将串行的元素取出,依次放入指定的变量中,然后循环执行命令区域(do和done 之间代码段),直到所有元素取尽为止。其中,串行是一些字符串的组合,彼此用 $ 或“空格”隔开,这些字符串称为字段。for循环的写法:

for  变量  in  串行    //串行有几个就执行几次循环
do
   执行命令       //要循环的部分
done

若串行是:A  B  C  D,那么变量变为A循环一次,变量变为B循环一次,依次类推,循环4次。

4.for循环数值处理,与C语言中很像,写法:
for((初始值;限制值;执行步长))
do
   执行命令       //要循环的部分
done

四、shell数学运算符(( ))

在 Bash Shell 中,如果不特别指明,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。

(( )):用于整数运算,但只能进行整数运算,不能对小数(浮点数)或者字符串进行运算。在 (( )) 中使用变量无需加上$前缀,(( )) 会自动解析变量名。

常见写法:
((a=10+66))
a=$((10+66))
((a>7 && b==c))
echo $((a+10))
((a=3+5, b=a+10))

let:用于整数运算,和 (()) 类似。
$[]:用于整数运算,不如 (()) 灵活。
bc:Linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器。

常用shell命令

下面列出一部分较为常用的一些Shell命令。

一、目录信息查看命令:ls(查看当前目录下的文件)。

ls后面可带不同的参数:

ls -a:显示所有文件及目录 (以 . 开头的隐藏文件也会列出)

ls -d:只列出目录(不递归列出目录内的文件)。

ls -l:显示文件和目录详细信息,包括权限、所有者、大小、创建时间等。

ls -r:倒序显示文件和目录。

ls -t:将按照修改时间排序,最新的文件在最前面。

ls -A:同 -a ,但不列出 "." (目前目录) 及 ".." (父目录)

ls -F:在列出的文件名称后加一符号;例如可执行档则加 "*", 目录则加 "/"。

ls -R:递归显示目录中的所有文件和子目录。

也可以组合起来使用,例如:

ls -al:显示所有文件及目录同时显示其权限、所有者、大小、创建时间等的详细信息。

二、目录切换命令:cd(进入某一个目录里面去)

返回上一级:cd ../,反回上两级:cd ../../。(依次类推)

如下图:cd + 空格 + /,再点击回车,就进入到Ubuntu的根目录。再用ls命令查看根目录下的信息。

下图,回到用户的根目录下面:cd /home/用户名,点击回车。

三、当前路径显示命令:pwd(查看当前所处目录 / 路径,进入深层文件夹里面可用此命令)
四、系统信息查看命令:uname

uname后面可带不同的参数:

-a 或--all 显示全部的信息,包括内核名称、主机名、操作系统版本、处理器类型和硬件架构等。

-m 或--machine 显示处理器类型。

-n 或--nodename 显示主机名。

-r 或--release 显示内核版本号。

-s 或--sysname 显示操作系统名称。

-v 显示操作系统的版本。

--help 显示帮助。

--version 显示版本信息。

-p 显示处理器类型(与 -m 选项相同)。

五、清理屏幕命令:clear(鼠标滚轮上拉上面还有之前的命令,并不是真的清屏)
六、显示文件内容命令:cat(查看某个文件的内容,注意:是查看文件不是查看文件夹)

显示文件内容,下面的示例中,它将显示/ etc / passwd文件的内容。

cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
narad:x:500:500::/home/narad:/bin/bash

在终端中查看多个文件的内容,下面示例中,将在终端中显示test和test1文件的内容。

cat test test1
Hello everybody
Hi world,

使用cat >test2命令创建一个名为test2文件的文件,并且等待用户输入所需的文本,然后按CTRL + D退出。文本将写入test2文件中。可用以下cat命令查看文件的内容。

cat test2
hello everyone, how do you do?

在文件中显示行号,使用-n选项,您可以在输出终端中看到文件song.txt的行号。

cat -n song.txt
1  "Heal The World"
2  There's A Place In
3  Your Heart
4  I Know 
5  And This Place Could
6  Be Much

一次显示多个文件。如下示例,有三个文件test,test1和test2,并且能够查看这些文件的内容。需要用;分隔每个文件。

cat test; cat test1; cat test2
This is test file.
This is test1 file.
This is test2 file.

将标准输出与重定向运算符一起使用。我们可以将文件的标准输出重定向到新文件,或者用' > '(大于)符号将其重新存在。如下:

# cat test > test1 //test1的现有内容将被test文件的内容覆盖。
# cat test >> test1 //测试文件的内容将附加在test1文件的末尾。
七、切换用户身份命令:sudo(切换到root模式,比如:在安装东西时候,需要有足够权限)

sudo -l:列出目前的权限

八、文件拷贝命令:cp

cp  a.c  b.c:拷贝一份a.c文件,重命名为b.c。

cp  file.txt  /path/to/destination/:将文件 file.txt 复制到目录 /path/to/destination/ 中。

cp -i 或 --interactive:在复制前提示确认,若目标文件已存在,询问是否覆盖,回答 y 则目标文件将被覆盖。

cp –r  test/  newtest 使用指令 cp -r 将当前目录 test/ 下的所有文件复制到新目录 newtest 下。

九、切换用户命令:su(sudo su:会进入root模式;sudo su lyp:切换回普通用户)如下图:

十、移动文件命令:mv(也是重命名命令,例如:mv  a.c  b.c:将a.c重命名为b.c)

mv-b:当目标文件或目录存在时,在执行覆盖前,会为其创建一个备份。

mv-i:如果指定移动的源目录或文件与目标的目录或文件同名,则会先询问是否覆盖旧文件,输入 y 表示直接覆盖,输入 n 表示取消该操作。

mv a_file(文件) b_file(文件)
将源文件名 a_file 改为目标文件名 b_file
mv a_file(文件) b_directory(目录)
将文件 a_file 移动到目标目录 b_directory 中
mv a_directory(目录) b_directory(目录)
目录名 b_directory 已存在,将 a_directory 移动到目录名 b_directory 中;目录名 b_directory 不存在则 a_directory 改名为目录名 b_directory
mv a_directory(目录) b_file(文件)
出错
十一、创建文件夹命令:mkdir

mkdir -p  runoob2/test:在工作目录下的runoob2目录中,建立一个名为 test 的子目录(子文件夹)。若 runoob2目录原本不存在,则建立一个。(注:本例若不加 -p 参数,且原本runoob2 目录不存在,则产生错误。)

十二、创建文件命令:touch

touch a.c:会在当前目录下创建一个a.c的文件。

十三、删除命令:rm(删除当前目录下指定的文件)

rm a.c(删除当前目录下的a.c文件)

rm -i:删除前逐一询问确认。

rm -f:即使原档案属性设为唯读,亦直接删除,无需逐一确认。

rm -r:将目录及以下之档案亦逐一删除。

rm -r *:删除当前目录下的所有文件及目录。

十四、目录删除命令:rmdir

rmdir -p:是当子目录被删除后使它也成为空目录的话,则顺便一并删除。

rmdir -p BBB/Test:在工作目录下的 BBB 目录中,删除名为 Test 的子目录。若 Test 删除后,BBB 目录成为空目录,则 BBB 亦予删除。

十五、显示网络配置信息命令:ifconfig

ifconfig后面可带不同的参数:

ifconfig add<地址> 设置网络设备IPv6的IP地址。

ifconfig del<地址> 删除网络设备IPv6的IP地址。

ifconfig <hw><网络设备类型><硬件地址> 设置网络设备的类型与硬件地址。

ifconfig io_addr<I/O地址> 设置网络设备的I/O地址。

ifconfig netmask<子网掩码> 设置网络设备的子网掩码。

ifconfig tunnel<地址> 建立IPv4与IPv6之间的隧道通信地址。

ifconfig -broadcast<地址> 将要送往指定地址的数据包当成广播数据包来处理。

ifconfig -pointopoint<地址> 与指定地址的网络设备建立直接连线,此模式具有保密功能。

启动和关闭指定网卡:

ifconfig eth0 down //关闭网卡:eth0
ifconfig eth0 up    //启动网卡:eth0

为网卡配置和删除IPv6地址

ifconfig eth0 add 33ffe:3240:800:1005::2/ 64 //为网卡eth0设置IPv6地址
ifconfig eth0 del 33ffe:3240:800:1005::2/ 64 //为网卡eth0删除IPv6地址

用ifconfig修改MAC地址

ifconfig eth0 down //关闭网卡
ifconfig eth0 hw ether 00:AA:BB:CC:DD:EE //修改MAC地址
ifconfig eth0 up //启动网卡

配置IP地址

ifconfig eth0 192.168.1.56 //给eth0网卡配置IP地址
ifconfig eth0 192.168.1.56 netmask 255.255.255.0 // 给eth0网卡配置IP地址,并加上子掩码
ifconfig eth0 192.168.1.56 netmask 255.255.255.0 broadcast 192.168.1.255 // 给eth0网卡配置IP地址,加上子掩码,加上个广播地址

启用和关闭ARP协议

ifconfig eth0 arp //开启
ifconfig eth0 -arp //关闭

设置最大传输单元

ifconfig eth0 mtu 1500 //设置能通过的最大数据包大小为 1500 bytes
十六、重启命令:reboot
十七、关机命令:poweroff
十八、系统帮助命令:man
十九、数据同步写入磁盘命令:sync

Linux 系统中欲写入硬盘的资料有的时候为了效率起见,会写到 filesystem buffer中,这个 buffer 是一块记忆体空间,如果欲写入硬盘的资料存于此 buffer 中,而系统又突然断电的话,数据尚未被写入硬盘当中,数据就会流失了。而sync指令会将存于buffer中的资料强制写入硬盘中。因此,不能用简单的关闭电源的方法关闭系统,因为Linux在内存中缓存了许多数据,在关闭系统时需要进行内存数据与硬盘数据的同步校验,保证硬盘数据在关闭系统时是最新的,只有这样才能确保数据不会丢失。一般正常的关闭系统的过程是自动进行这些工作的,在系统运行过程中也会定时做这些工作,不需要用户干预。

二十、查找文件命令:find

find -name pattern按文件名查找,支持使用通配符 * 和 ?

find -type type按文件类型查找,可以是 f(普通文件)、d(目录)、l(符号链接)等。

find -size [+-]num[单位]:按文件大小查找,使用 + 或 - 表示大于或小于指定大小,单位:可以是 c(字节)、w(字)、b(块数)、k(KB)、M(MB)或 G(GB)。

find -mtime days按修改时间查找,使用 + 或 - 表示在指定天数前或后,days 是个整数表示天数。

find  . -name  file.txt:查找当前目录下名为 file.txt 的文件。

find . -name "*.c":将当前目录及其子目录下所有文件后缀为 .c 的文件列出来。

find . -type f:将当前目录及其子目录中的所有文件列出。

find /home -size +1M:查找 /home 目录下大于1MB 的文件。

find /var/log -mtime +7:查找 /var/log 目录下在 7 天前修改过的文件。

二十一、查找内容命令:grep

Linux grep命令用于查找文件里符合条件的字符串或正则表达式。

grep-i:忽略大小写进行匹配。

grep-v:反向查找,只打印不匹配的行。

grep-n:显示匹配行的行号。

grep-r:递归查找子目录中的文件。

grep-l:只打印匹配的文件名。

grep-c:只打印匹配的行数。

grep  hello  file.txt:在文件 file.txt 中查找字符串 "hello",并打印匹配的行。

grep -r -n pattern dir/:在文件夹 dir 中递归查找所有文件中匹配正则表达式 "pattern" 的行,并打印匹配行所在的文件名和行号。

echo "hello world" | grep -c world:在标准输入中查找字符串 "world",并只打印匹配的行数。

grep test *file:在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行。

二十二、文件夹大小查看命令:du

Linux du命令用于显示目录或文件的大小。

-h或--human-readable 以K,M,G为单位显示目录所占空间,提高信息的可读性。

-s显示目录占用的磁盘大小,不要显示其下子目录和文件占用的磁盘大小。

例如:du /lib -sh:查看Ubuntu下面的lib库的大小。

二十三、磁盘空间检查命令:df

Linux df命令用于显示目前在 Linux 系统上的文件系统磁盘使用情况统计。

二十四、使用gedit 打开某个文件命令:gedit

Linux命令gedit主要作用是:启动Ubuntu桌面环境下的文本编辑器gedit。

gedit是一个GNOME桌面环境下兼容UTF-8的文本编辑器,使用GTK+编写而成,支持包括gb2312、gbk在内的多种字符编码。

gedit的启动有两种方式,一种是从桌面菜单启动:应用程序、附件、文本编辑器;另一种是从命令行执行以下命令: gedit。

二十五、当前的系统进程查看命令:ps(与Windows下的任务管理器类似)

ps -A:列出所有的进程

ps -w:显示加宽可以显示较多的资讯

ps -au:显示较详细的资讯

ps -aux:显示所有包含其他使用者的进程

二十六、进程实时运行状态查看命令 top(实时显示各任务的进程,运行状态)

top -d <秒数>:指定 top 命令的刷新时间间隔,单位为秒。

top -n <次数>:指定 top 命令运行的次数后自动退出。

top -p <进程ID>:仅显示指定进程ID的信息。

top -u <用户名>:仅显示指定用户名的进程信息。

top -H:在进程信息中显示线程详细信息。

top -i:不显示闲置(idle)或无用的进程。

top -b:以批处理(batch)模式运行,直接将结果输出到文件。

top -c:显示完整的命令行而不截断。

top -S:累计显示进程的 CPU 使用时间。

二十七、文件类型查看命令:file

Linux file命令用于辨识文件类型。通过file指令,我们得以辨识该文件的类型。

file -b:列出辨识结果时,不显示文件名称。

file -c:详细显示指令执行过程,便于排错或分析程序执行的情形。

file -f <名称文件>:指定名称文件,其内容有一个或多个文件名称时,让file依序辨识这些文件,格式为每列一个文件名称。

file -L:直接显示符号连接所指向的文件的类别。

file -v:显示版本信息。

file -z:尝试去解读压缩文件的内容。

二十八、gcc命令

在Linux系统中,gcc命令用于编译和链接C和C++程序。它是GNU编译器套件(GNU Compiler Collection)的一部分。

以下是gcc命令的基本语法和常用选项:

gcc  [选项]  源文件(s)  -o  输出文件

gcc -o <输出文件>:指定输出文件的名称。

gcc -c:只进行编译,生成目标文件,不进行链接。

gcc -Wall:显示所有编译警告信息。

gcc -Werror:将警告视为错误,编译过程中如果有警告将会终止。

gcc -std=<标准>:指定所使用的C或C++语言标准,如-std=c11表示使用C11标准。

gcc -lm:在链接过程中加入数学库,通常用于需要使用数学函数的程序。

gcc -I<目录>:添加头文件搜索路径。

gcc -L<目录>:添加库文件搜索路径。

gcc -l<库名>:链接指定的库文件。例如,-lm表示链接数学库。

gcc -g:生成调试信息,可以在程序调试时使用。

写在最后:shell命令还有很多,会随着后面学习慢慢补充。最后希望本文可以帮助到各位读者,文章如有不足,欢迎大家指出,如果文章帮到你了,请一定帮忙点个赞哦。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值