嵌入式 Linux Shell编程

简介: 嵌入式 Linux Shell编程

1、shell脚本

什么是 Shell,就是命令解析器,将用户输入的指令转换为相应的机器能够运行的程序。

Shell 脚本是一个包含一系列命令序列的文本文件。当运行这个脚本文本时,文件中包含的命

令序列将得到执行。

如果我们有一系列经常使用的 Linux 命令,我们可以把它们存储在一个文件中。Shell 可以读

取这个文件并执行其中的命令。这样的文件被称为脚本文件。

2、执行shell脚本

要创建一个shell脚本,我们可以使用任何编译器,比如vim在文本文件中编写它,习惯保存的文件后缀为.sh(仅为了识别是shell脚本文件)

vi aa.sh -->创建并进入 vi 编辑器编写 shell 脚本

chmod +x aa.sh -->给 shell 脚本加上可执行权限

bash aa.sh -->linux 命令行下执行 shell 脚本,此方法可以不设置执行权限

或./aa.sh -->此方法需要设置执行权限

或 sh aa.sh -->此方法可以不设置执行权限

3、shell脚本编写

shell 脚本的编写语法如下:

1)程序往往以#!/bin/bash 的行开始,这一行不是注释而是 shell 脚本的标识。

2)以#作为语句的注释

3)shell 变量,命令,关键字语法等

3.1 shell变量

shell 变量没有数据类型,都是字符串,即使数值也是字符串。

创建(定义)变量:变量名称=值。 #等号两边不能有空格

注意:如果值有空格则必须用""或者’’引用起来

示例: test.sh

shell 变量没有数据类型,都是字符串,即使数值也是字符串。
创建(定义)变量:变量名称=值。 #等号两边不能有空格
注意:如果值有空格则必须用""或者’’引用起来

注意:''和" "的区别:

单引号:消除所有字符的特殊意义。

双引号:消除除了$、" "、' '三种以外其它字符的特殊意义。

1>: #echo $a

等同于#echo ${a}

或#echo "${a}"

2>: #echo "hello b$aa" 输出 hello b;

3>: #echo "hello b${a}a" 输出:hello bhelloa

4>: #echo "${a}a" 输出:helloa

5>: #echo '${a}a' 输出:${a}a,因为' '会消除特殊字符的意义

6>: #echo '\${a}a' 输出:\${a}a

删除变量:unset 变量名

变量的其他常用方法:

比如:要2.sh要求输入2个数计算2个数的和

#!/bin/bash
#this is my second shell project
echo "please input the first number:"
read a
echo "please input the second number:"
read b
c=$(($a + $b))
echo "The result of $a + $b is $c"

重定向符号:

[root@localhost second]# echo hello > 1 将内容 hello 输入到 1 文件里
[root@localhost second]# cat < 1 > 2 cat 从 1 文件里获取内容,输出到 2 文件里
[root@localhost second]# cat 2 查看 2 文件里的内容
hello
[root@localhost second]#

管道:

管道操作符 |

“|”符用于连接左右两个命令,将“|”左边的命令执行结果(输出)作为“|”右边命令的

输入

cmd1 | cmd2

在同一条命令中可以使用多个“|”符连接多条命令

cmd1 | cmd2 | ... | cmdn

[root@localhost shell]# ps -ef

[root@localhost shell]# ps -ef |grep bash

例子;写 1.sh 要求读入 1 个目录名,在当前目录下创建该目录,并复制 etc 下的 conf 文件到该目录,统计 etc 下所有目录的数目到 etcdir.txt 中

#!/bin/bash
#this is my first shell project
read dir #从命令行读入一个字符串
mkdir ${dir} #在当前目录下创建目录
cp -rf /etc/*conf ${dir} #复制 etc 下的 conf 文件到该目录
ls -l /etc/* | grep ^d > etcdir.txt
[root@localhost shell]# vim 1.sh
[root@localhost shell]# chmod +x 1.sh
[root@localhost shell]# ./1.sh
12
[root@localhost shell]# cd 12/
[root@localhost 12]# ls -l
总用量 292
-rw-r--r--. 1 root root 391 8 月 7 15:36 ant.conf
-rw-r--r--. 1 root root 245 8 月 7 15:36 anthy-conf
......
[root@localhost 12]# cd ..
[root@localhost shell]# cat etcdir.txt
drwxr-xr-x. 2 root root 4096 8 月 1 06:42 plugins
drwxr-xr-x. 2 root root 4096 8 月 1 07:00 actions
......
[root@localhost shell]#

3.2 标准变量或环境变量

系统预定义的变量,一般在/etc/profile 中进行定义。

HOME :用户主目录 PATH 文件搜索路径。

PWD :用户当前工作目录。

PS1、PS2 :提示符。

LOGNAME:指登录主机的用户名称;

HOSTNAME :主机名字,也就是这个系统的名字。

USER:指目前环境使用者的名称。

还有其他的系统变量

例如:

定义本地变量:name="Red Hat Linux"

export name:把 name 变为全局变量。

或直接输出 export name="Red Hat Linux"

由父 shell 进入子 shell 后,可以使用父 shell 的全局变量,而本地变量不可以。

示例:

[root@localhost shell]# ./2.sh

[root@localhost shell]# vim 1.sh

[root@localhost shell]# chmod +x 1.sh

[root@localhost shell]# ./1.sh

12

[root@localhost shell]# cd 12/

[root@localhost 12]# ls -l

总用量 292

-rw-r--r--. 1 root root 391 8 月 7 15:36 ant.conf

-rw-r--r--. 1 root root 245 8 月 7 15:36 anthy-conf

......

[root@localhost 12]# cd ..

[root@localhost shell]# cat etcdir.txt

drwxr-xr-x. 2 root root 4096 8 月 1 06:42 plugins

drwxr-xr-x. 2 root root 4096 8 月 1 07:00 actions

......

[root@localhost shell]#

3.4 变量赋值有五种格式

例子:

a=1
echo ${a} #1
echo ${a:+2} #2
echo ${a:-2} #1
echo ${a:?2} #1
echo ${a:=2} #1
echo ${b} #显示空
echo ${b:+2} #显示空
echo ${b:-2} #2
echo ${b:?2} #./4.sh: line 11: b: 2 显示错误信息
echo ${b:=2} #显示空

3.5 运算符和表达式

关系运算符

布尔运算

3.6 Test命令用法

VAR=2

test $VAR -gt 1

echo $?

也可以写为

VAR=2

[ $VAR -gt 3 ] #中括号两边必须要有空格

echo $?

1、判断表达式

2、判断字符串

注意:在 = 前后各有一个空格。如果忘记加空格,那就不是比较关系了,而变成了赋值语句。

比较字符序列大小时候,需要在 > 或 < 前面加转义字符 \

a="abc"
test $a == "abc"
echo $?
test $a != "afd"
echo $?
#字符串拼接
str1="abcd"
str2="fgjgh$str1"
echo $str2

3.判断整数

test 整数 1 –eq 整数 2 -->整数相等为真

-ge 大于等于

–gt 大于

–le 小于等于

–lt 小于

–ne 不等于

4、判断文件

test File1 –ef File2 两个文件具有同样的设备号和 i 结点号

test File1 –nt File2 文件 1 比文件 2 新

test File1 –ot File2 文件 1 比文件 2 旧

test –b File 文件存在并且是块设备文件

test –c File 文件存在并且是字符设备文件

test –d File 文件存在并且是目录

test –e File 文件存在

test –f File 文件存在并且是普通文件

test –g File 文件存在并且是设置了组 ID

test –G File 文件存在并且属于有效组 ID

test –h File 文件存在并且是一个符号链接(同-L)

test –k File 文件存在并且设置了 sticky 位

test –L File 文件存在并且是一个符号链接(同-h)

test –o File 文件存在并且属于有效用户 ID

test –p File 文件存在并且是一个命名管道

test –r File 文件存在并且可读

test –s File 文件存在并且是一个套接字

test –t File 文件描述符是在一个终端打开的

test –u File 文件存在并且设置了它的 set-user-id 位

test –w File 文件存在并且可写

test –x File 文件存在并且可执行

3.7 数组

1、数组定义

定义 1: a=(1 2 3 4 5) #下标从 0 开始 各个数据之间用空格隔开
定义 2: a[0]=1;a[1]=2;a[2]=3
定义 3: a=([1]=1 [2]=2)

2、引用 ¥ {a[1]}

3.8 if语句

形式 1:

if[condition]

then

action

fi

只有当 condition 为真时,该语句才执行操作,否则不执行操作,并继续执行“fi”之后的任

何行。

形式 2:

if [ condition ]

then

action

elif [ condition2 ];then

action2

. . .

elif [ condition3 ];then

else

actionx

fi

在使用时,将“if”和“then”放在不同行,如同行放置,则 if 语句必须要“;”结束。

举例:

#!/bin/bash
file="./a.c"
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi

用参数传 1 个文件名,该文件如果是文件并且可读可写就显示该文件,如果是目录就进入该目

录,并判断 ls.sh 存在否,如果不存在就建立 1 个 ls.sh 的文件并运行该文件。

该文件的内容是 ls -li /etc > etc.list

#!/bin/bash
if [ -f $1 -a -r $1 -a -w $1 ] #判断是普通文件并可读可写
then
cat $1 #显示文件内容
elif [ -d $1 ] #否则如果是目录
then
cd $1 #进入目录
fi
if [ -e ls.sh ] #如果 ls.sh 该文件存在
then
chmod +x ls.sh #赋予可执行的权限
./ls.sh #执行
else
touch ls.sh #如果不存在则创建 ls.sh
echo "#!/bin/bash" >> ls.sh #将程序写入 ls.sh 中保存
echo "ls -li /etc > etc.list" >> ls.sh #将要执行的命令写入 ls.sh 中保存
chmod +x ls.sh #赋予可执行的权限
./ls.sh
fi

shell 编程中使用到得 if 语句内文件判断参数:

–b 当 file 存在并且是块文件时返回真

-c 当 file 存在并且是字符文件时返回真

-d 当 pathname 存在并且是一个目录时返回真

-e 当 pathname 指定的文件或目录存在时返回真

-f 当 file 存在并且是正规文件时返回真

-g 当由 pathname 指定的文件或目录存在并且设置了 SGID 位时返回为真

-h 当 file 存在并且是符号链接文件时返回真,该选项在一些老系统上无效

-k 当由 pathname 指定的文件或目录存在并且设置了“粘滞”位时返回真

-p 当 file 存在并且是命令管道时返回为真

-r 当由 pathname 指定的文件或目录存在并且可读时返回为真

-s 当 file 存在文件大小大于 0 时返回真

-u 当由 pathname 指定的文件或目录存在并且设置了 SUID 位时返回真

-w 当由 pathname 指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然

是可执行的。

-o 当由 pathname 指定的文件或目录存在并且被子当前进程的有效用户 ID 所指定的用户拥有时返

3.9 case语句

case常用的语法形式如下:

case $1 in
"1")
echo you inputed "1"
;;
"2")
echo you inputed "2"
;;
*)
echo you inputed other number
;;
esac

例子:智能解压文件

说明,创建一个压缩包,压缩包的后缀为.zip或者.gzip或者.bzip2格式,并且传递参数的时候也需要把这个后缀名写上

#!/bin/sh
ftype=`file "$1"` #file 用于判断$1 的文件类型,并保存到 ftype 中
case "$ftype" in
"$1: Zip archive"*)
unzip "$1"
;;
"$1: gzip compressed"*)
gunzip "$1"
;;
"$1: bzip2 compressed"*)
bunzip2 "$1"
;;
*)
echo "File $1 can not be uncompressed with smartzip"
;;
esac
#终端输入格式
#[root@localhost auto]# ./aa.sh cc.txt.zip

3.10 for循环

格式:

for 变量名 in 列表

     do

        命令

 done

例子:

i=0
for i in 1 2 3 4 5
do
echo $i
done
或者:
i=0
for ((i=0;i<5;i++))
do
echo $i
done

例子:冒泡排序

#!/bin/bash
a=(3 10 6 5 9 2 8 1 4 7)
for(( i=1; i<10; i++ ))
do
for(( j=0; j<10-i; j++ ))
do
if [ ${a[j]} -gt ${a[j+1]} ]
then
temp=${a[j]}
a[j]=${a[j+1]} #或者 a[j]=${a[$(($j+1))]}
a[j+1]=$temp
fi
done
done
for(( i=0; i<10; i++ ))
do
echo ${a[i]}
done

3.11 while语句

#!/bin/bash
#this is my first shell project
loopcount=0
result=0
while [ $loopcount -lt 100 ]
do
loopcount=$(($loopcount + 1))
result=$(($loopcount + $result))
done
echo "The result of \'1+2+3+...+100\' is $result"
#!/bin/bash
a=(3 10 6 5 9 2 8 1 4 7)
x=0
while [ $x -lt ${#a[*]} ]
do
echo ${a[$x]}
x=$(($x + 1))
done
#!/bin/bash
a=(3 10 6 5 9 2 8 1 4 7)
i=0
while (( i<10 )) #类似 C 语言的写法
do
echo ${a[i]}
i=$(($i+1))
done

3.12 until 语句

myvar=0
until [ $myvar -eq 10 ]
do
echo $myvar
myvar=$(($myvar+1))
done

3.13 shell 函数

函数名() {命令1.... ...}

function 函数名() {.... ...}

关键字 function 表示定义一个函数,可以省略,其后是函数名,有时函数名后可以跟一个括

号,符号“{”表示函数执行命令的入口,该符号也可以在函数名那一行,“}”表示函数体的结束,

两个大括号之间是函数体。

语句部分可以是任意的 Shell 命令,也可以调用其他的函数。

如果在函数中使用 exit 命令,可以退出整个脚本,通常情况,函数结束之后会返回调用函数的部分继续执行。可以使用 break 语句来中断函数的执行

函数参数的传递

函数可以通过位置变量传递参数。例如

函数名 参数 1 参数 2 参数 3 参数 4

当函数执行时,$1 对应参数 1,其他依次类推

函数的返回值

函数中的关键字“return”可以放到函数体的任意位置,通常用于返回某些值,Shell 在执行

到 return 之后,就停止往下执行,返回到主程序的调用行,return 的返回值只能是 0~256 之间的

一个整数,返回值将保存到变量“$?”中

#!/bin/bash
#declare a function named hello
function hello()
{
echo "Hello,$1 today is `date`"
return 11
}
echo "now going to the function hello"
hello "I love china" #hello 函数的参数为 I love china,即$1 为 I love china
echo $? #输出 hello 这个函数的返回值
echo "back from the function"

4、综合实例

#!/bin/bash
while true #表示死循环
do
echo "============================"
echo "*******student system*******"
echo " 1.create operator "
echo " 2.insert operator "
echo " 3.delete operator "
echo " 4.append operator "
echo " 5.update operator "
echo " 6.find operator "
echo " 7.print operator "
echo " 0.exit operator "
echo "****************************"
echo "============================"
echo "please input your operator:"
read op
clear #清屏
case $op in
"1")
echo "create student succeed!"
#clear
;;
"2")
echo "insert student succeed!"
#clear
;;
"3")
echo "delete student succeed!"
#clear
;;
"4")
echo "append student succeed!"
#clear
;;
"5")
echo "update student succeed!"
#clear
;;
"6")
echo "find student succeed!"
esac
done


相关文章
|
1天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
29 13
|
22天前
|
存储 Shell Linux
Linux 如何更改默认 Shell
Linux 如何更改默认 Shell
30 0
Linux 如何更改默认 Shell
|
2月前
|
Web App开发 网络协议 Linux
linux命令总结(centos):shell常用命令汇总,平时用不到,用到就懵逼忘了,于是专门写了这篇论文,【便持续更新】
这篇文章是关于Linux命令的总结,涵盖了从基础操作到网络配置等多个方面的命令及其使用方法。
78 1
linux命令总结(centos):shell常用命令汇总,平时用不到,用到就懵逼忘了,于是专门写了这篇论文,【便持续更新】
|
2月前
|
存储 移动开发 网络协议
【实战指南】从零构建嵌入式远程Shell,提升跨地域协作效率(2)
本文《从零构建嵌入式远程Shell》的第二部分,介绍了如何通过模块化设计和功能增强来优化远程Shell,包括支持阻塞命令、增加用户主动结束Shell进程的能力等,提升了跨地域协作效率。文中提供了详细的代码示例和验证步骤,适合开发者深入学习。
56 9
|
1月前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
2月前
|
Shell
Shell编程(下)
Shell编程(下)
110 1
|
2月前
|
Shell Linux Windows
Shell编程(上)
Shell编程(上)
47 1
|
2月前
|
Shell Linux 开发工具
|
2月前
|
存储 Shell Linux
【Linux】shell基础,shell脚本
Shell脚本是Linux系统管理和自动化任务的重要工具,掌握其基础及进阶用法能显著提升工作效率。从简单的命令序列到复杂的逻辑控制和功能封装,Shell脚本展现了强大的灵活性和实用性。不断实践和探索,将使您更加熟练地运用Shell脚本解决各种实际问题
36 0
|
消息中间件 缓存 Unix
[面试必备]嵌入式Linux内核开发必须了解的三十道题
[面试必备]嵌入式Linux内核开发必须了解的三十道题