高级Bash脚本编程指南_第1页
高级Bash脚本编程指南_第2页
高级Bash脚本编程指南_第3页
高级Bash脚本编程指南_第4页
高级Bash脚本编程指南_第5页
已阅读5页,还剩78页未读 继续免费阅读

下载本文档

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

文档简介

1、高级Bash脚本编程指南:从一个简单的script出发成于坚持,败于止步开始shell脚本编程学习,路途遍布荆棘啊,O(_)O,开始吧,这是“高级Bash脚本编程指南”为我们量身打造的“HelloWorld”,其实也不算,因为这个只是我们无比熟悉的命令的堆叠嘛!O(_)O清除/var/log下的log文件htmlview plaincopy1. #清除,当然要使用root身份来运行这个脚本.2. 3. cd/var/log4. cat/dev/nullmessages5. cat/dev/nullwtmp6. echoLogscleanedup.像分析helloworld 一样,我们也说下这个

2、shell脚本吧!这根本就没什么稀奇的, 只不过是命令的堆积, 来让从console或者xterm中一个一个的输入命令更方便一些. 好处就是把所有命令都放在一个脚本中,不用每次都敲它们. 这样的话, 这个脚本就成为了一个工具, 对于特定的应用来说,这个脚本就很容易被修改或定制.其中,第一条#后面带一句话,你该猜到了,没错,这是注释,将来你会经常和他打交道,先见下面吧cd /var/log 这简单,我天天在用,我就别废话了cat /dev/null messages 这个前面简单我也天天用,不过后面是什么,有可能就像“仝”这个字,上下分开,一年级小学生都会,可是这样拼在一起,就不一定了,具体是什

3、么字自己去查哈,这里告诉这条语句的作用是把cat /dev/null 得到的内容保存到messages中,先混个脸熟吧下一句你该乐了,该学了一招嘛但是这里我还是决定多花点时间说说这里的这个/dev/null,因为也许你还不知道为什么要保存到messages和wtmp中,而且cat 的为什么是/dev/null在Linux操作系统中/dev/null和/dev/zero是两个相似却又很特殊的文件,特别是在shell脚本开发和系统运维过程中会经常用这两个文件,因此作为Linux系统工程师,你必须了解这两个文件的区别和用法。一、/dev/null的用法:我们可以把/dev/null文件看作”黑洞”,

4、它非常等价于一个只写文件,所有写入/dev/null文件的内容都会丢失,而从/dev/null文件中也读取不到任何内容。然而,也正因为这些特点,在shell脚本开发和命令行维护时,/dev/null文件就可大展身手,显得非常的有用。1. 禁止标准输出例如:cat查看$filename文件,其回显信息将为空htmlview plaincopy1. #cat$filename/dev/null2. 禁止标准错误例如:rm删除文件时,若$badname文件不存在,那么如下的方式则会过滤回显的错误信息htmlview plaincopy1. #rm$badname2/dev/null3. 禁止标准输出

5、和标准错误的输例如:cat查看$filename文件htmlview plaincopy1. #cat$filename2/dev/null/dev/null# 如果”$filename”不存在,将不会有任何错误信息提示.# 如果”$filename”存在, 文件的内容不会打印到标准输出.# 因此上面的代码根本不会输出任何信息.4. 清除日志文件内容例如:htmlview plaincopy1. #cat/dev/null/var/log/wtmp2. #cat/dev/null/var/log/messages# : /var/log/messages 有同样的效果, 但不会产生新的进程.(

6、因为:是内建的)这里你还要知道怎么就会清空了wtmp和messages这两个文件呢?因为你cat /dev/null的结果为空啊,然后你又把空内容保存到这两个文件中,不就相当于清空嘛5. /dev/null的特殊用法,程序打印的日志将不再记录,避免系统空间被不需要的日志所占用稍微高级一点的,例如:htmlview plaincopy1. #ln-s/dev/null/.netscape/cookies将该cookie的日志文件链接到/dev/null,那么往该文件中写入的内容都将被抛弃二、/dev/zero的用法:/dev/zero和/dev/null一样,也是一个伪文件,但/dev/zero

7、实际上能产生连续不断的null的流(二进制的零流,而不是ASCII型的),写入/dev/zero的输出会丢失不见,而从/dev/zero读出一连串的null也比较困难,虽然这也能通过dd或一个十六进制编辑器来做到,/dev/zero主要的用处是用来创建一个指定长度用于初始化的空文件,它通常都是配合dd命令一起使用的。1. 用/dev/zero创建一个指定大小的临时文件例如:结合dd命令可创建一个大小为1024*1000bit的文件/swap,当然这个文件的大小可通过bs和count参数去调整htmlview plaincopy1. #ddif=/dev/zeroof=/swapbs=1024c

8、ount=10002. 通过/dev/zero将零填充到一个指定大小的文件,以使用某些特殊需求例如:把RAM设备的内容用零填充,从而实现格式化RAM的目的htmlview plaincopy1. #ddif=/dev/zeroof=$DEVICEcount=$SIZEbs=$BLOCKSIZE综上所述,/dev/null和/dev/zero文件的区别和用法如下:/dev/null文件是空设备,也称为位桶(bit bucket),它主要是用于“被写入”,任何写入它的输出都会被抛弃。如果不想让消息以标准输出显示或写入文件,那么可以将消息重定向到/dev/null。因此凡是向/dev/null输入的

9、任何数据,它通吃,并且不会撑着!/dev/zero文件主要是用作一个标准的“0”输入设备,它可无穷尽地提供0,可以使用/dev/zero来初始化文件。清除:一个改良的清除脚本htmlview plaincopy1. #!/bin/bash2. LOG_DIR=/var/log3. cd$LOG_DIR4. cat/dev/nullmessages5. cat/dev/nullwtmp6. echoLogscleanedup.7. exit# 这个命令是一种正确并且合适的退出脚本的方法,算是比较标准的“helloworld”现在,让我们看一下一个真正意义的脚本,而且我们可以走得更远 ,这里只是将

10、上面的单条命令汇总到一个bash文件中一并处理,俗称“批处理”清除: 一个增强的和广义的删除logfile的脚本htmlview plaincopy1. #!/bin/bash2. LOG_DIR=/var/log3. ROOT_UID=04. LINES=105. E_XCD=666. E_NOTROOT=677. 8. if$UID-ne$ROOT_UID9. then10. echoMustberootrorunthisscript!11. exit$E_NOTROOT12. fi13. 14. #if-n$115. #then16. #lines=$117. #else18. #lin

11、es=$LINES19. #fi20. 21. E_WORNGPARAM=6522. case$1in23. )lines=10;24. *!0-9*)echoUsage:wongparam!;exit$E_WRONGPARAM;25. *)lines=$1;26. esac27. 28. #cd$LOG_DIR29. #if$PWD!=$LOG_DIR30. #then31. #echoCantchangeto$LOG_DIR32. #exit$E_XCD33. #fi34. 35. cd/var/log|36. echoCantchangetonecessarydirectory.&237

12、. exit$E_XCD38. 39. 40. tail-$linesmessagesmesg.tmp41. mvmesg.tmpmessages42. 43. cat/dev/nullmessages44. cat/dev/nullwtmp45. echoLogscleanedup!46. exit0因为你可能希望将系统log全部消灭, 这个版本留下了log消息最后的部分. 你将不断地找到新的方法来完善这个脚本,并提高效率.要注意,在每个脚本的开头都使用 sha-bang ( #!), 这意味着告诉你的系统这个文件的执行需要指定一个解释器. #! 实际上是一个2字节的魔法数字, 这是指定一个

13、文件类型的特殊标记, 换句话说, 在这种情况下, 指的就是一个可执行的脚本(键入man magic来获得关于这个迷人话题的更多详细信息). 在sha-bang之后接着是一个路径名. 这个路径名就是解释脚本中命令的解释程序所在的路径, 可能是一个shell, 也可能是一个程序语言, 也可能是一个工具包中的命令程序.这个解释程序从头开始解释并且执行脚本中的命令(从sha-bang行下边的一行开始), 忽略注释.这里强调文件中的第一个sha-bang才有意义,并且必须在开头,之后如果再次出现sha-bang不会解析为sha-bang,举例说明如下:htmlview plaincopy1. #!/bi

14、n/bash2. echoPart1ofscript.3. a=14. 5. #!/bin/bash#这将不会启动一个新脚本.6. echoPart2ofscript.7. echo$a每一个脚本头的行都指定了一个不同的命令解释器, 如果是/bin/sh, 那么就是默认shell (在Linux系统上默认就是bash), 否则的话就是其他解释器.举例说明如下:htmlview plaincopy1. #!/bin/rm2. #自删除脚本.作为rm命令,直接删除自己,more命令显示自己的内容3. #当你运行这个脚本时,基本上什么都不会发生.当然这个文件消失不见了.4. WHATEVER=65e

15、choThislinewillneverprint(betcha!).5. exit$WHATEVER#不要紧,脚本是不会在这退出的.使用#!/bin/sh, 因为大多数的商业UNIX系统上都是以Bourne shell作为默认shell, 这样可以使脚本移植到non-Linux的机器上, 虽然这将会牺牲Bash一些独特的特征. 但是脚本将与POSIX的sh标准相一致.注意sha-bang后边给出的路径名必须是正确的, 否则将会出现一个错误消息 - 通常是Command not found - 这将是你运行这个脚本时所得到的唯一结果.当然#!也可以被忽略, 不过这样你的脚本文件就只能是一些命令

16、的集合, 不能够使用shell内建的指令了. 上边第二个例子必须以#!开头, 是因为分配变量了, lines=50, 这就使用了一个shell特有的用法. 再次提醒你#!/bin/sh将会调用默认的shell解释器, 在Linux机器上默认是/bin/bash.这里对上面的脚本做以下分析:1.定义变量2.检查脚本是否获取到root权限,采用两种方式,一种便于理解,一种更加专业一点的做法3.检查输入参数,采用两种方式,一种便于理解,一种更加专业一点的做法4.检查是否进入/var/log目录,采用两种方式,一种便于理解,一种更加专业一点的做法5.执行cleanup动作最后鼓励你使用模块化的方式来编

17、写脚本. 平时也要多注意收集一些比较有代表性的 模版代码, 这些零碎的代码可能用在你将来编写的脚本中. 最后你就能生成一个很好的可扩展的例程库. 以下边这个脚本为例, 这个脚本用来测试脚本被调用的参数数量是否正确.大多数情况下,你需要编写一个脚本来执行一个特定的任务, 在本章中第一个脚本就是一个这样的例子, 然后你会修改它来完成一个不同的, 但比较相似的任务. 使用变量来代替写死(硬编码(hard-wired)的常量, 就是一个很好的习惯, 将重复的代码放到一个函数中,也是一种好习惯.高级Bash脚本编程指南(2):Shell特殊字符成于坚持,败于止步# 注释1. 表示注释2. 在引号中间和#

18、等表示#本身3.echo $PATH#*: # 参数替换,不是一个注释4.echo $( 2# ) # 数制转换,不是一个注释; 分隔1.命令分隔,在一行中写多个命令 echo aa ; echo bb2.在条件中的if和then如果放在同一行,也用;分隔; case条件的结束1.命令分隔,在一行中写多个命令 echo aa ; echo bb2.在条件中的if和then如果放在同一行,也用;分隔htmlview plaincopy1. echohello;echothere2. if-x$filename;then#注意:if和then需要分隔.3. echoFile$filenameexi

19、sts.;cp$filename$filename.bak4. else5. echoFile$filenamenotfound.;touch$filename6. fi;echoFiletestcomplete. 命令相当于1.命令:source2.文件名的前缀,隐藏文件3.目录:.当前目录,.父目录4.正则表达式:匹配任意单个字符首先,先举例说明一下.作为source使用的实例htmlview plaincopy1. #!/bin/bash2. .data-file#加载一个数据文件.3. #与sourcedata-file效果相同,但是更具可移植性.4. #文件data-file必须存在

20、于当前工作目录,因为这个文件是使用basename来引用的.5. echovariable1=$variable16. echovariable3=$variable37. letsum=$variable2+$variable48. echosum=$sum9. exit0上面是编写的data_file脚本,通过 . data-file引入,相当于c语言中的include data-file,我们看看data-file的内容htmlview plaincopy1. #这是需要被脚本加载的数据文件.2. #这种文件可以包含变量,函数,等等.3. #在脚本中可以通过source或者.命令来加载.

21、4. #让我们初始化一些变量.5. variable1=226. variable2=4747. variable3=58. variable4=979. message1=Hello,howareyou?10. message2=Enoughfornow.Goodbye.接下来我们看看脚本的执行结果:htmlview plaincopy1. rootubuntu:/resource/study/shell_study#chmod777include_file2. rootubuntu:/resource/study/shell_study#ls3. clear_logdata-fileinc

22、lude_fileshow_self4. rootubuntu:/resource/study/shell_study#./include_file5. variable1=226. variable3=57. sum=571上面的结果已经很有力的说明了我们想要的结论.作为隐藏文件时,建立隐藏文件的方法:touch .data-file.作为匹配字符说明如下:ab. 可以表示ab+任意字符,处理换行,并且必须是一个字符ab.不能表示ab 部分引用 支持通配符扩展STRING将会阻止(解释)STRING中大部分特殊的字符 全引用,不进行通配符扩展STRING将会阻止STRING中所有特殊字符的解

23、释. 这是一种比使用更强烈的形式 转义X将会转义字符X. 这等价于X, 也等价于X. 通常用来转义和, 这样双引号和单引号就不会被解释成特殊含义了./ 目录分隔符分隔文件名不同的部分(比如 /home/bozo/projects/Makefile).也可以用来作为除法算术操作符., 多个命令都被执行,但返回最后一个逗号操作符链接了一系列的算术操作. 虽然里边所有的内容都被运行了,但只有最后一项被返回.htmlview plaincopy1. lett2=(a=9,15/3)#Seta=9andt2=15/3逗号之前会运算,但是只有最后一项被返回 后置引用command结构可以将命令的输出赋值到

24、一个变量中去.htmlview plaincopy1. cd$LOG_DIR2. ifpwd!=$LOG_DIR3. then4. echoCantchangeto$LOG_DIR5. exit$E_XCD6. fi这里例子是最有力的的说明,在上一章中只不过没有到这个方法,这里pwd命令会返回当前路径,然后与LOG_DIR进行比较,同样你可以定义一个变量保存pwd返回的内容,比如:path=pwd: 操作符1.空操作,等价于NOP (no op, 一个什么也不干的命令).2.死循环: while :,可以被认为与shell的内建命令,与true作用相同.htmlview plaincopy1.

25、 while:2. do3. operation-14. operation-25. .6. operation-n7. done# 与下边相同:htmlview plaincopy1. #whiletrue2. #do3. #.4. #done3.在if/then中表示什么都不做,引出分支htmlview plaincopy1. ifcondition2. then:#什么都不做,引出分支.3. else4. take-some-action5. fi4.设置默认参数 : $username=whoamihtmlview plaincopy1. :$username=whoami2. #$u

26、sername=whoami如果没有开头的:的话,将会给出一个错误,除非username是一个命令或者内建命令5.变量替换 : $HOSTNAME? $USER? $MAIL?htmlview plaincopy1. :$HOSTNAME?$USER?$MAIL?2. #如果一个或多个必要的环境变量没被设置的话,就打印错误信息.6.在和 (重定向操作符)结合使用时,把一个文件截断到0 长度,没有修改它的权限;如果文件在之前并不存在,那么就创建它.如: data.xxx #文件data.xxx现在被清空了. 与 cat /dev/null data.xxx 的作用相同 然而,这不会产生一个新的进

27、程,因为:是一个内建命令.7.可能用来作为注释行, 虽然我们不推荐这么做. 使用#来注释的话, 将关闭剩余行的错误检查, 所以可以在注释行中写任何东西. 然而, 使用:的话将不会这样.: This is a comment that generates an error, ( if $x -eq 3 ).8.:还用来在/etc/passwd和$PATH变量中做分隔符.htmlview plaincopy1. bash$echo$PATH2. /usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games* 匹配0个或

28、多个字符;数学乘法;*幂运算htmlview plaincopy1. rootubuntu:/resource/study/shell_study#ls2. clear_logdata-fileinclude_fileshow_self3. rootubuntu:/resource/study/shell_study#echo*4. clear_logdata-fileinclude_fileshow_self? 匹配任意一个字符;但在(ab?a:b)表示c语言中的三目运算( t = acombined_file2. #把file1,file2,file3连接在一起,并且重定向到combine

29、d_file中.3. 4. 5. cpfile22.txt,backup6. #拷贝file22.txt到file22.b 代码块,即一个匿名函数,但其中定义的变量在后面依然可用htmlview plaincopy1. #!/bin/bash2. #从/etc/fstab中读行.3. File=/etc/fstab4. 5. readline16. readline27. readline38. test-context#把代码块中的所有输出都重定向到文件中.8. 9. echoResultsofrpmtestintest-context10. exit0看看运行结果:htmlview pla

30、incopy1. rootubuntu:/resource/study/shell_study#chmod777test22. rootubuntu:/resource/study/shell_study#./test23. Resultsofrpmtestintest-context4. rootubuntu:/resource/study/shell_study#ls5. clear_loginclude_fileshow_selftest26. data-filepara_subtest1test-context7. rootubuntu:/resource/study/shell_st

31、udy#cattest-context8. Justforatest:9. /root/resource/study/shell_study10. Testend ; 用在find的-exec中 $find -name *.txt -exec cat ; 字符1.测试 -z $12.数组元素 a1=test3.表示测试 使用 . 条件判断结构, 而不是 . , 能够防止脚本中的许多逻辑错误. 比如, &, |, 操作符能够正常存在于 条件判断结构中, 但是如果出现在 结构中的话, 会报错.4.( )数学运算5.在正则表达式中表示范围 a-z 重定向和进程替换 ls -al a.txtscrip

32、tname filename 重定向scriptname的输出到文件filename中. 如果filename存在的话, 那么将会被覆盖.command &filename 重定向command的stdout和stderr到filename中.command &2 重定向command的stdout到stderr中.scriptname filename 把scriptname的输出追加到文件filename中. 如果filename不存在的话, 将会被创建.ifilename 打开文件filename用来读写, 并且分配文件描述符i给这个文件. 如果filename不存在, 这个文件将会被创

33、建. 还用在ASCII比较 if $veg1 $veg2 正则表达式中的单词边界.如:bash$grep textfile| 管道分析前边命令的输出, 并将输出作为后边命令的输入. 这是一种产生命令链的好方法.echo ls -l | sh # 传递echo ls -l的输出到shell中,与一个简单的ls -l结果相同.cat *.lst | sort | uniq # 合并和排序所有的.lst文件, 然后删除所有重复的行.管道是进程间通讯的一个典型办法, 将一个进程的stdout放到另一个进程的stdin中. 标准的方法是将一个一般命令的输出, 比如cat或者echo, 传递到一个 过滤命

34、令(在这个过滤命令中将处理输入)中, 然后得到结果.cat $filename1 $filename2 | grep $search_word当然输出的命令也可以传递到脚本中.htmlview plaincopy1. #!/bin/bash2. #uppercase.sh:修改输入,全部转换为大写.3. tra-zA-Z4. #字符范围必须被引用起来来阻止产生单字符的文件名.5. exit0现在让我们输送ls -l的输出到一个脚本中.htmlview plaincopy1. bash$ls-l|./uppercase.sh2. -RW-RW-R-1BOZOBOZO109APR719:491.T

35、XT3. -RW-RW-R-1BOZOBOZO109APR1416:482.TXT4. -RW-R-R-1BOZOBOZO725APR2020:56DATA-FILE管道中的每个进程的stdout比须被下一个进程作为stdin来读入. 否则, 数据流会阻塞, 并且管道将产生一些非预期的行为.cat file1 file2 | ls -l | sort# 从cat file1 file2中的输出并没出现.作为子进程的运行的管道, 不能够改变脚本的变量.variable=initial_valueecho new_value | read variableecho variable = $vari

36、able # variable = initial_value如果管道中的某个命令产生了一个异常,并中途失败,那么这个管道将过早的终止. 这种行为被叫做broken pipe, 并且这种状态下将发送一个SIGPIPE 信号.| 强制重定向(即使设置了noclobber 选项-就是-C 选项).这将强制的覆盖一个现存文件.| 逻辑或操作 ;用在两个命令之间的时候,表示在前一个命令结束时,若返回值为 false,继续执行下一个命令& 逻辑与;用在两个命令之间的时候,表示在前一个命令结束时,若返回值为 true,继续执行下一个命令& 后台运行看一个例子htmlview plaincopy1. #!/

37、bin/bash2. #background-loop.sh3. foriin12345678910#第一个循环.4. do5. echo6. echo-n$i7. done&#在后台运行这个循环.8. 9. #在第2个循环之后,将在某些时候执行.10. echo#这个echo某些时候将不会显示.11. foriin11121314151617181920#第二个循环.12. do13. echo-n$i14. done15. echo#这个echo某些时候将不会显示.16. exit0看一下结果:htmlview plaincopy1. rootubuntu:/resource/study/

38、shell_study#./for_test2. 3. 111213141516171819204. rootubuntu:/resource/study/shell_study#5. 16. 27. 38. 49. 510. 611. 712. 813. 914. 10- 在所有的命令内如果想使用选项参数的话,前边都要加上-.1.参数选项2. 减号3. 重定向stdin和stdout:cd /source/directory & tar cf - . ) | (cd /dest/directory & tar xpvf -)4.先前的工作目录 cd -5.注:使用-开头的文件名和变量名可能会

39、出现一些问题+ 一个命令或者过滤器的选项标记. home目录+ 当前工作目录- 先前工作目录 正则表达式中表示行首其中命令的很多细节并没有研究的很彻底,好多好碎,以后见到用到具体的命令再具体分析吧高级Bash脚本编程指南(3):变量和参数的介绍成于坚持,败于止步变量替换变量的名字就是变量保存值的地方. 引用变量的值就叫做变量替换.“$“这个符号就好像是一种标志让我们仔细的区别变量的名字和变量的值. 如果variable是一个变量的名字, 那么$variable就是引用这变量的值, 即这边变量所包含的数据.htmlview plaincopy1. rootubuntu:#variable=122

40、. rootubuntu:#echovariable3. variable4. rootubuntu:#echo$variable5. 12当变量没有$前缀的时候,那么变量可能存在如下几种情况.1.变量被声明或被赋值,2.变量被unset,3.变量被exporte,4.变量处在一种特殊的情况,变量代表一种信号变量赋值可以使用=(比如 var1=27), 也可以在read命令中或者循环头进行赋值 (for var2 in 1 2 3).被一对双引号( )括起来的变量替换是不会被阻止的. 所以双引号被称为部分引用, 有时候又被称为弱引用. 但是如果使用单引号的话( ), 那么变量替换就会被禁止了,

41、 变量名只会被解释成字面的意思, 不会发生变量替换. 所以单引号被称为全引用, 有时候也被称为强引用.注意$variable事实上只是$variable的简写形式. 在某些上下文中$variable可能会引起错误, 这时候你就需要用$variable了下面以一个例子做说明htmlview plaincopy1. #!/bin/bash2. #变量赋值和替换3. a=375#这里没有$说明是声明并且赋值了4. hello=$a#$a表示使用变量a的值,把这个值赋值给hello这个变量5. #-6. #强烈注意,在赋值的的时候,等号前后一定不要有空格.7. #如果出现空格会怎么样?8. #VARI

42、ABLE=value9. #脚本将尝试运行一个VARIABLE的命令,带着一个=value参数.10. #VARIABLE=value11. #脚本将尝试运行一个value的命令,并且带着一个被赋值成的环境变量VARIABLE.12. #-13. echohello#没有$这里打印hello变量的名字14. echo$hello#打印hello变量的值15. echo$hello#同样是打印hello变量的值16. 17. echo$hello18. echo$hello19. 20. hello=ABCD#重新赋值21. echo$hello#ABCD引用一个变量将保留其中的空白,当然,如果是变量替换就不会保留了.2

温馨提示

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

评论

0/150

提交评论