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