《 Linux操作系统(第四版)》 课件 第7章 shell编程基础_第1页
《 Linux操作系统(第四版)》 课件 第7章 shell编程基础_第2页
《 Linux操作系统(第四版)》 课件 第7章 shell编程基础_第3页
《 Linux操作系统(第四版)》 课件 第7章 shell编程基础_第4页
《 Linux操作系统(第四版)》 课件 第7章 shell编程基础_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章shell编程基础本章导读shell编程是Linux自动化运维的核心技能。本章从shell与脚本基础讲起,系统介绍重定向与管道、变量与运算、条件测试、流程控制及函数,并讲解脚本排错方法。学完本章,你将能够编写结构清晰、逻辑正确的shell脚本,把重复操作转化为自动化任务。学完本章,您将能够01.说明shell的作用,编写并运行第一个shell脚本。02.运用重定向、管道及变量运算处理文本流与数据。03.使用条件测试与if/case、for/while/until等语句实现流程控制。04.定义和调用shell函数,提升脚本的模块化与可复用性。05.借助sh-x/-v与语法检查手段定位并修正脚本错误。第7章shell编程基础01.shell与脚本基础理解shell环境,掌握脚本的编写、执行与基本结构。02.编程基础运用重定向、管道、变量、条件测试与流程控制语句。03.程序排错识别脚本错误类型,使用调试跟踪手段保障脚本正确运行。7.1shell基础介绍shell简介编写shell脚本7.1.1shell简介shell概述:shell是一个用C语言编写的命令解释器;shell还是一门编程语言。shell脚本一般应用于重复性的操作、批量化的事务处理、自动化的运维管理、对服务器运行状态的监控、定时任务执行等场景。要编写shell脚本,首先应该熟练使用shell命令和掌握shell编程语句。shell发展史:V6shell--Bourneshell(sh)--Cshell(csh)--tcsh--Kornshell(ksh)--Bourne-Againshell(Bash)。Bash是当今世界上最流行的shell,它兼容sh、csh、ksh,是Linux系统的默认shell,故本章仍默认使用Bashshell。查看和设置用户shell。

示例1:登录openEuler,查看系统默认安装的shell。

[root@openEulerZYC~]#cat/etc/shells

/bin/sh

/bin/bash

/usr/bin/sh

/usr/bin/bash

示例2:查看并更改当前用户的默认shell。

示例3:查看当前用户的shell。7.1.1shell简介7.1.2编写shell脚本1.shell脚本基础知识学会编写规范、易读的shell脚本,可以提高日常任务的自动化程度和准确性。形式最简单的shell脚本就是一系列shell命令构成的可执行文件,并可以被其他脚本复用。shell脚本适用于可以通过调用其他命令行工具来完成的任务。7.1.2编写shell脚本2.编写shell脚本代码及其基本规范(1)脚本文件的构成一个基本完善的shell脚本文件,由脚本声明、注释信息、有效代码这三部分构成。出于规范和安全的考虑,一般在shell脚本的第一行通过脚本声明指定执行此脚本的解释器。在shell脚本中使用注释信息用来解释后续一行或多行代码所要实现的功能。注释信息所在行的行首使用“#”作为标识。7.1.2编写shell脚本2.编写shell脚本代码及其基本规范(2)使用文本编辑器编写脚本代码可以在任意文本编辑器(如高级编辑器Vim、Emacs等)中打开新文件来创建shell脚本。Vim在识别文件的后缀为.sh后可以提供语法高亮、检查、补全等功能。如图所示:

使用示例:编写一个简单的shell脚本,依次输入shell命令。7.1.2编写shell脚本3.执行shell脚本(1)方式一:filename赋予脚本可执行权限。若脚本所在路径包含在$PATH变量中,则可以通过在命令行中直接输入该脚本文件名来调用,否则必须写出该脚本的执行路径(绝对路径或相对路径)。若shell脚本文件就在当前目录下,通常写成“./filename”形式。

7.1.2编写shell脚本3.执行shell脚本(2)方式二:shfilename无需赋予脚本可执行权限。sh命令是bash命令的符号链接,故这两个命令是等效的。sh(bash)命令会在当前shell环境下启动一个新的shell子进程。在该子shell中读入并执行路径为filename的脚本文件。sh(bash)命令可以利用“-n”选项检查shell脚本的语法,利用变量增强“-x”选项逐条跟踪Shell脚本语句的输出信息。

7.1.2编写shell脚本3.执行shell脚本(3)方式三:sourcefilename无需赋予脚本可执行权限。source命令(来源于Cshell)等效于点命令(“.”,来源于Bourneshell),是Bashshell的内置命令。source命令用于在当前shell环境下读入并执行路径为filename的脚本文件。即该命令不会启动一个新的shell子进程,所有在脚本中设置的变量将成为当前shell的一部分。

7.1.2编写shell脚本3.执行shell脚本关于在后台执行shell脚本:有时候一些脚本执行时间较长,命令行界面会被占用,因此可以采取后台运行脚本(command&)。#./my_script.sh&使用上述方法,脚本进程会随着退出shell而终止。可以通过将脚本的标准输出和标准错误输出重定向到文件nohup.out中,来保证脚本的持续运行(nohupcommand&)。#nohup./my_script.sh&

使用jobs命令可以查看后台中运行着的进程。

7.2shell编程基础重定向和管道shell变量及运算条件测试流程控制语句函数7.2.1重定向和管道1.文本流文本流存在于Linux的每一个进程中,Linux的每个进程启动时,会打开三个文本流的端口(交互式设备):标准输入、标准输出、标准错误,它们分别对应着一个进程的输入、输出和异常的抛出,相关说明见表7-1。使用示例:观察标准输入、标准输出和错误输出。表7-1关于三类端口的说明类型描述设备文件文件描述编号默认设备标准输入接受用户输入数据的设备/dev/stdin0键盘标准输出向用户输出数据的设备/dev/stdout1显示器标准错误输出报告执行出错信息的设备/dev/stderr2显示器2.重定向(1)输入重定向输入重定向:command<inputfile内联输入重定向(把字符串string作为标准输入开始和结束的标识)command<<string>……>string(2)输出重定向输出重定向(覆盖):command>outputfile输出重定向(追加):command>>outputfile

7.2.1重定向和管道2.重定向

(3)典型用法使用以下命令行将输入的数据即时保存为一个文件。输入的数据可以是即时输入的文本(以string作为起止标识),也可以是一个文件(以string为文件名)。command<<string>file使用示例7.2.1重定向和管道表7-2重定向操作符及其说明类型操作符描述输入重定向<从指定的文件读入数据<<从即时输入的文本读入数据输出重定向>将输出结果保存到指定的文件(覆盖原有内容)>>将输出结果追加到指定的文件末尾错误输出重定向2>将错误信息保存到指定的文件(覆盖原有内容)2>>将错误信息追加到指定的文件末尾混合输出重定向&>将标准输出、标准错误的内容保存到同一个文件中3.管道将一个命令的输出结果作为另一个命令的输入(处理对象)。管道(|)实际上是进程间通信(IPC)的一种方式,它就像现实中的运输管路一样,可以连接两个命令的输入和输出,还可以串联多个命令。语法格式:command1|command2[|…|commandN]使用示例示例1:从/etc/passwd文件中提取出每个用户的账户名和默认Shell。示例2:查看当前已挂载文件系统的类型及使用率。7.2.1重定向和管道7.2.2shell变量及运算1.shell中的特殊字符和其他编程语言一样,shell也有一些保留字(特殊字符),在编写脚本时需要注意。shell中的特殊字符及其具体说明见表7-3。特殊字符名称作用及说明#注释符在shell文件第一行的首部标记解释器,如:#!/bin/sh;在shell文件其他行的首部作为注释使用,该行后面的内容不会被执行。‘’单引号单引号包裹的内容被视为单一字符串,禁止变量扩展。即单引号中的所有字符包括变量和特殊字符都将被解释为该字符本身。“”双引号双引号包裹的内容允许变量扩展。即双引号中的变量和特殊字符都会被展开,如通过$、“、”、\等特殊字符可以调用变量的值、引用命令、实现字符转义等。``反引号/撇号命令替换,提取命令执行后的输出结果。“command”相当于$(command)。\转义符放在特殊字符之前,使特殊字符失去特殊含义,仅表示特殊字符本身,这在字符串中常用。如:\$将输出“$”本身,而不是作为变量引用;放在一行命令的末端,表示紧接着的回车无效(转义了Enter),后继新行的输入仍然作为当前命令的一部分。/路径分隔符/运算符作为路径分隔符,以斜杆(根目录)开头的路径为绝对路径;作为运算符,表示除法符号。如:a=4/2。!逻辑非表示反逻辑,如:“!=”表示不等于;表示取反,如:命令“lsa[!0-9]”列出以a开头且后面不紧接一个数字的文件。表7-3shell中的特殊字符7.2.2shell变量及运算2.shell变量变量用于为程序传递特定参数。通过一个变量,我们可以使用shell脚本在一块内存区域中存储数据,也可以引用一块内存区域中的数据,变量名就是这块内存区域上贴的一个标签。shell与其他强类型的编程语言如C、Java、C++等差异很大:shell中的变量是无类型的。变量值能够根据用户设置、系统环境的变化而变化。(1)变量定义/赋值:变量的定义就是以固定的名称存放可以变化的值。方式一:variable=value方式二:使用read命令从标准输入中读入一行(各参数以空格分隔),分解储存若干部分,分别复制给read命令后面的变量名列表中各对应的变量。read[-p“提示信息”]变量名列表7.2.2shell变量及运算2.shell变量(2)变量作用域及类型变量作用域:变量总体上分为全局变量和局部变量。全局变量作用于整个shell会话及其所有子shell;局部变量仅作用于定义它们的进程及其子进程内。变量具体分为以下几种类型:环境变量:属于全局变量,由操作系统提前创建、维护并用于设置用户的工作环境,存储在配置文件/etc/profile、~/.bash_profile中。设置环境变量:export变量名”或“export变量名=变量值显示环境变量:printenv[$变量名]env[|grep$变量名]echo$变量名常见环境变量:PATH、PWD、USER、UID、HOME、SHELL、PS17.2.2shell变量及运算2.shell变量(2)变量作用域及类型变量具体分为以下几种类型:位置变量:是shell的内置变量,用于在命令行、函数或脚本中传递参数。位置变量用“$N”或“${N}”表示,N表示参数的序数$1—$9返回接收到第一个到第九个参数第九个之后的位置参数需要用{}把序数括起来,例如:${10}。预定义变量:与前面介绍的环境变量相似,也是Shell的内置变量,在shell启动时就定义好了。与环境变量不同的是,预定义变量是只读的。所有预定义变量都是由“$”符号和另一个符号组成的位置变量也可以看作一种预定义变量7.2.2shell变量及运算2.shell变量(2)变量作用域及类型常用的shell预定义变量见表7-4所示。特殊字符作用及说明$0当前执行的shell脚本文件名(进程名)。$#脚本、函数、命令携带的参数的个数。${!#}如有参数,则返回接收到的最后一个参数,否则返回脚本文件名本身。$*和$@都可以用来访问脚本、函数、命令携带的所有参数,但两者含义略有区别:变量$*会将接收到的所有参数当作一个单词保存;变量$@会将接收到的所有参数当作同一字符串中的多个独立的单词。$?上一条命令的退出状态码,或函数的返回值。0表示执行正常,非0值表示执行异常或出错。$$当前shell进程的ID。对于shell脚本,就是这些脚本所在的进程ID。$!后台运行的最后一个进程的ID。表7-4shell中的预定义变量7.2.2shell变量及运算2.shell变量(2)变量作用域及类型变量具体分为以下几种类型:自定义变量:除了系统定义的环境变量外,用户还可以按照一定的语法规则自行定义、修改和使用变量。自定义变量默认为局部变量,也可以定义为全局变量。设置自定义变量格式一:variable=value格式二:readonlyvariable=value(用于定义只读变量)格式三:exportvariable=value(用于定义全局变量)显示自定义变量使用set命令查看当前Shell进程的所有变量和函数对于定义为全局的变量,可以使用printenv命令和env命令列出。7.2.2shell变量及运算2.shell变量(3)变量引用/访问方式一:$变量名说明:引用/访问变量的值方式二:${变量名}说明:引用/访问变量的值且需要接其他数据7.2.2shell变量及运算3.shell的算术运算默认情况下,shell不会直接进行算术运算,而必须使用数学计算命令。(1)Shell的算术扩展语法格式:$[表达式]说明:算术扩展可用于执行简单的整数运算。VAR=$[$1+$2]等效于((VAR=$1+$2))或VAR=‘expr$1+$2’。expr命令的语法格式为“expr变量1算术运算符变量2[运算符变量3……]”,注意运算符左右两边要有空格。与大部分编程语言不同,在默认情况下,Bashshell不会区分变量类型,因此,shell会把运算符直接当作字符串连接符,最终的结果是把两个字符串拼接在一起形成一个新的字符串。7.2.2shell变量及运算3.shell的算术运算(2)算术运算符及其优先级执行算术运算离不开各种运算符。常见的shell算术运算符见表7-5所示。在表中,运算符的优先级按由高到低顺序排列。表7-5shell算术运算符及其优先级运算符说明/含义<VARIABLE>++、<VARIABLE>--变量后置递增(自增)和变量后置递减(自减)++<VARIABLE>、--<VARIABLE>变量前置递增(自增)和变量前置递减(自减)**幂运算*、/、%乘法、除法、求余(取模)+、-加法、减法7.2.2shell变量及运算3.shell的算术运算(3)数学计算命令在Shell中必须使用命令进行数学计算。shell中常用的数学计算命令见表7-6。表7-6shell中常用的六种数学计算方式运算操作符/运算命令说明(())用于整数运算,效率很高,推荐使用。let用于整数运算,和(())类似。$[]用于整数运算,不如(())灵活。expr可用于整数运算,也可以处理字符串。使用时需注意细节。bcLinux下的一个计算器程序,可以处理整数和小数。shell本身只支持整数运算,要计算小数就得使用bc这个外部的计算器。推荐使用。declare-i将变量定义为整数,然后再进行数学运算时就不会被当做字符串了。功能有限,仅支持最基本的数学运算(加减乘除和求余),不支持逻辑运算、自增自减等,所以在实际开发中很少使用。1.条件测试的语法格式在shell程序中,进行条件测试通常使用以下格式:[测试表达式]注意:在上面的格式中,中括号“[]”与测试表达式之间必须有一个空格来分隔。2.判断命令执行结果执行任何Linux命令都可能存在两种状态:正确或错误。若前一条命令正确执行,则返回的状态值为0;若返回值非0,则表示执行前一条命令出错。使用预定义变量“$?”可返回命令执行后的状态。在shell程序中可以根据预定义变量“$?”的值,来判断前一条命令执行是否正确。7.2.3条件测试3.判断文件/目录7.2.3条件测试操作符说明[-aFILE]如果FILE存在,则返回为真。[-bFILE]如果FILE存在且为块设备文件,则返回为真。[-cFILE]如果FILE存在且为字符设备文件,则返回为真。[-dFILE]如果FILE存在且为目录,则返回为真。[-eFILE]如果FILE存在,则返回为真。[-fFILE]如果FILE存在且为普通文件,则返回为真。[-gFILE]如果FILE存在且设置了SGID位,则返回为真。[-hFILE]如果FILE存在且为符号链接文件,则返回为真。(该选项在一些老系统上无效)[-kFILE]如果FILE存在且设置了sticky位,则返回为真。[-pFILE]如果FILE存在且为命令管道,则返回为真。[-rFILE]如果FILE存在且可读,则返回为真。[-sFILE]如果FILE存在且大小非零(至少有一个字符),则返回为真。[-uFILE]如果FILE存在且设置了SUID位,则返回为真。[-wFILE]如果FILE存在且可写,则返回为真。[-xFILE]如果FILE存在且可执行,则返回为真。[-OFILE]如果FILE存在且属有效用户ID,则返回为真。[-GFILE]如果FILE存在且默认组为当前组,则返回为真。(只检查系统默认组)[-LFILE]如果FILE存在且为符号链接文件,则返回为真。[-SFILE]如果FILE存在且为套接字,则返回为真。[FILE1-ntFILE2]如果FILE1比FILE2新,或者FILE1存在但是FILE2不存在,则返回为真。[FILE1-otFILE2]如果FILE1比FILE2旧,或者FILE2存在但是FILE1不存在,则返回为真。[FILE1-efFILE2]如果FILE1和FILE2指向相同的设备和节点号,则返回为真。表7-7文件/目录判断操作4.判断数值7.2.3条件测试表7-8数值判断操作操作符说明[INT1-eqINT2]如果INT1和INT2两数值相等,则返回为真。与高级程序语言中的“==”类似。[INT1-neINT2]如果INT1和INT2两数值不相等,则返回为真。与高级程序语言中的“!=”或“<>”类似。[INT1-gtINT2]如果INT1大于INT2,则返回为真。与高级程序语言中的“>”类似。[INT1-geINT2]如果INT1大于等于INT2,则返回为真。与高级程序语言中的“>=”类似。[INT1-ltINT2]如果INT1小于INT2,则返回为真。与高级程序语言中的“<”类似。[INT1-leINT2]如果INT1小于等于INT2,则返回为真。与高级程序语言中的“<=”类似。5.判断字符串7.2.3条件测试表7-9

字符串判断操作操作符说明[-zSTRING]如果STRING的长度为零,则返回为真。即空是真。[-nSTRING]如果STRING的长度非零,则返回为真。即非空是真。[STRING1]如果STRING1的长度非零,则返回为真。即非空是真,与-n类似。[STRING1==STRING2]如果两个字符串相同,则返回为真。[STRING1!=STRING2]如果两个字符串不相同,则返回为真。[STRING1<STRING2]如果“STRING1”字典排序在“STRING2”前面,则返回为真。[STRING1>STRING2]如果“STRING1”字典排序在“STRING2”后面,则返回为真。6.判断逻辑7.2.3条件测试表7-10

逻辑判断操作操作符说明[!EXPR]逻辑非,如果EXPR为false则返回为真(对已有逻辑值取反)。[EXPR1-aEXPR2]逻辑与,如果EXPR1为true并且EXPR2为true则返回为真(当两个测试条件都成立时才返回真值)。[EXPR1-oEXPR2]逻辑或,如果EXPR1为true或者EXPR2为true则返回为真(只要两个测试条件中有一个条件成立就返回真值)。[]||[]逻辑或,用OR来合并两个条件。[]&&[]逻辑与,用AND来合并两个条件。在shell脚本里除了顺序执行,还需要一些额外的逻辑控制流程。和其他编程语言类似,shell中的流程控制语句主要包括条件、循环两大类。1.条件语句(1)if-else条件语句if条件测试命令串then条件为真时执行的命令else 条件为假时执行的命令fiBashshell会先执行if后面的语句,如果其退出状态码为0,则会继续执行then部分的命令,否则会执行脚本中的下一个命令。7.2.4流程控制语句1.条件语句(2)if-elif-else条件语句if条件测试命令串1then 条件1为真时执行的命令elif条件测试命令串2then条件2为真时执行的命令……elif条件测试命令串nthen 条件n为真时执行的命令else 条件n为假时执行的命令fi7.2.4流程控制语句1.条件语句(3)case条件语句case$变量名in模式1|模式2) 分支1执行的命令序列1;;模式3) 分支2执行的命令序列2;; ……模式n) 分支n执行的命令序列n;;*) 默认执行的命令序列esac7.2.4流程控制语句2.循环语句循环语句用于一些需要重复执行的任务,直到满足特定条件为止。常见的循环语句有三种:for、while、until。用于控制循环流程的转向的循环控制符有两种:break、continue。(1)for循环语句:对每一个变量可能的值循环执行一段命令序列。赋给变量的数值既可在程序内以数值列表的形式提供,也可在程序外以位置参数的形式提供。语法格式一:shell风格for$变量名in值列表do 循环执行的命令序列done 语法格式二:C语言风格for((定义变量;测试条件;变量迭代过程))do 循环执行的命令序列done7.2.4流程控制语句2.循环语句(2)while和until循环语句两者都通过命令的返回状态值来控制循环是否要继续执行。两者跳出循环的条件判断正好相反:while循环仅在“条件测试命令串”返回真(0)时继续执行循环,而until循环则是仅在“条件测试命令串”返回假(非0)时继续执行循环。为避免死循环,必须保证循环体中包含循环出口条件。while循环:也称为前测试循环语句while条件测试命令串do循环执行的命令序列doneuntil循环:也称为后测试循环语句until条件测试命令串do循环执行的命令序列done 7.2.4流程控制语句2.循环语句(3)break和continue语句在循环执行的命令序列中,有时可能需要根据条件退出循环或跳过一些循环步,这时可使用break和continue语句。使用break语句结束整个循环体,也就是立即退出循环;使用contiune语句结束单次循环,也就是不再执行当前循环后面的语句,立即开始下一次循环的执行。这两个语句只有放在循环语句的do和done之间才有效。使用命令“exit0”可以立即退出整个程序。当脚本遇到exit命令时,脚本将立即退出并跳过对脚本其余内容的处理。7.2.4流程控制语句在shell中,允许将一组命令集或语句组成一个可重复使用的块,这些块称为shell函数。shell函数定义的基本格式为:函数名(){命令序列}在shell程序中,直接以函数名的形式调用函数。7.2.5函数7.3shell程序排错shell脚本错误类型调试跟踪语法风格7.3.1

shell脚本错误类型编写、使用或维护Shell脚本的管理员不可避免地会遇到脚本的错误。错误通常是由于输入错误、语法错误或脚本逻辑不佳导致的。1.一般错误常见的输入错误有:输入错误关键字、不区分大小写字母、漏输入字符等。shell的循环控制语句与一般高级程序语言有所不同,输入结构时容易出错。在编写脚本时,将文本编辑器与Bash语法高亮显示结合使用,可以帮助使输入错误、语法错误更明显。2.逻辑错误一个程序能顺利执行,但执行结果错误,这称为逻辑错误,最难发现和解决。找到并排除脚本中错误尤其是逻辑错误,最直接方法是进行调试。对于逻辑错误,通常的做法是对程序中的变量值进行跟踪,查看在不同状态下变量值是否按设计的过程发生变化。可通过执行sh命令的方式来调用shell程序,从而对程序的执行过程进行跟踪。sh命令主要通过两个选项(-v和-x)来跟踪Shell程序的执行。v选项:使shell在执行过程中,将读入的每条命令行都原样输出到中断。x选项:使shell在执行过程中,在执行的每条命令行首用一个“+”号加上对应的命令显示在终端上,并把每一个变量和该变量的值也显示出来。shell扩展的执行结果会显示在打印输出中,所有变量数据状态会实时打印,以供跟踪。每条命令执行完后都有一个返回状态,也称为退出代码。退出代码可以用于脚本的调试。7.3.2

调试跟踪7.3.3

语法风格避免在脚本中引入错误的另一种简单方法是在创建脚本期间遵循良好的语法风格。以下是一些建议和具体做法:将长命令分解为多行更小的代码块,短的代码段更便于读者领悟和理解;将多个语句的开头和结尾排好,以便于查看控制结构的开始和结束位置以及它们是否正确关闭;对包含多行语句的行做缩进,以表示代码逻辑的层次结构和控制结构的流程;使用行间距分隔命令块,以阐明一个代码段何时结束以及另一代码段何时开始;在整个脚本中使用一致的格式;适当添加注释和空格能够极大改善脚本可读性。做到以上这些,就能极大地方便用户在编写期间发现错误,还提高了脚本可读性。本章小结本章围绕shell编程基础,系统介绍了shell的作用、脚本的基本结构、变量与运算的用法,以及条件判断和循环等流程控制语句。通过典型示例,读者可以

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论