收藏 分销(赏)

shell脚本重点笔记专业资料.doc

上传人:w****g 文档编号:2953858 上传时间:2024-06-12 格式:DOC 页数:44 大小:173.04KB 下载积分:12 金币
下载 相关 举报
shell脚本重点笔记专业资料.doc_第1页
第1页 / 共44页
shell脚本重点笔记专业资料.doc_第2页
第2页 / 共44页


点击查看更多>>
资源描述
#!/bin/sh   第一某些 UNIX和SHELL工具 [1] 四、使用文献 ls ls –F 用附加字符来标示列出来条目文献类型。 ls –d 只显示目录名字,不显示它内容。 mkdir –p /dir1/file1 如果父目录不存在,创立父目录 cat cat –n file1 输出每一行带编号 cat –b file1 输出空白行不编号 wc 参数: -l 记录行数 -w 记录单词数 -m 记录字符数 linux中没有 -c 记录字符数 linux中有 cp cp src1 … srcN dest 拷贝各种文献 cp –i file1 file2 交互模式,覆盖会提问 cp –r dir1 dir2 拷贝目录 mv mv src1 … srcN dest 移动各种文献 mv –i file1 file2 交互模式,覆盖会提问 rm rm –i file1 交互模式,覆盖会提问 [2] 五、输入与输出 1、输出到终端 echo echo str 输出str echo命令使用转义序列(在ksh中有效,bash中无效)(该转义序列也可用于printf) \n 打印换行 \t 打印tab字符 \c 背面不默认跟随换行,打印一种字符串 echo “Your fruit basket contains:\napple orange pear” printf printf命令要在字符串后输出换行,必要在所要打印字符串后明确指定\n转义序列,而echo命令会自动打印出换行。 e.g. echo “Is that a mango?” 等于 printf “Is that a mango?\n” printf 基本语法 printf format arguments format格式序列形式如下: %[-]m.nx %标示格式序列开始,x指明格式序列类型,下表给出了x也许得值 字母 描述 字母 描述 s 字符串 o 八进制数 c 字符 e 指数浮点数 d 十进制整数 f 固定浮点数 x 十六进制数 g 紧密浮点数 依照x值不同,整数m和n有不同解释。普通,m是域最小长度,而n是域最大长度。如果你指定一种实数,n就被作为应当用到精度,连字符 – 表在左边对齐一种域。默认状况下,所有域都是在右边对齐. e.g. printf “%-16s\t%-16s\n” “Name” “User Name” 表达左对其,输出被分隔为两列,每16个字符长度被空格分隔开。 2、输出重定向 cmd > file 可以将命令列表输出重定向 e.g. { date ;uptime ;who ;} > mylog cmd >> file 追加到文献 cmd | tee file 将输出从定向到文献和屏幕,使用tee 命令 e.g. date | tee now 输出到屏幕同步写入文献now 3、输入重定向 cmd < file cmd << delimiter shell将操作符<<解释为如下指令:shell读取顾客输入,直到遇到某一行,其中包括指定delimiter。直到浮现包括delimiter行,前面所有输入行都作为命令cmd原则输入。delimiter必要是不涉及空格或tab单词。 e.g. cat > file1 <<MYURLS MYURLS 输入MYURLS后,退出 4、读取顾客输入 read name 该命令读取顾客输入,直到顾客按回车键,命令将把输入字符串分派到name指定变量。 | 管道 e.g. ps –ael |grep “$UID” |more 5、文献描述符 ,也叫文献句柄 3个原则文献描述符 当执行任何命令时,3个文献被打开并和该命令有关联。3个原则文献描述符如下 阐明 文献名 文献描述符 原则输入 STDIN 0 原则输出 STDOUT 1 原则错误 STDERR 2 使用文献描述符和文献关联 能使用exec命令将任何文献和文献描述符关联 exec n>file exec n>>file 其中n为文献描述符 e.g. exec 4>file.out 把文献file.out和文献描述符4关联起来 注意: exec 1>file.out 则所有输出都将被放到file.out中,在终端屏幕上将什么也看不见 普通输入/输出重定向 将指定命令cmd输出重定向到指定文献 cmd n> file cmd n>> file e.g. ls 1>file 将ls命令原则输出到file. 重定向原则输出和原则错误到单独文献 cmd 1> file1 2>file2 由于文献描述符1可以被省略,上面命令可以简化为 cmd >file1 2>file2 cmd 1>>file1 2>>file2 cmd >>file1 2>>file2 重定向原则输出和原则错误到同一种文献 cmd 1>file 2>&1 等于 cmd >file 2>& cmd 1>>file 2>&1 等于 cmd >>file 2>& 打印消息到原则输出 echo str 1>&2 等于 echo str >&2 printf format args 1>&2 等于 printf format args >&2 重定向一种文献描述符输出到另一种文献描述符 格式为: n>&m n和m都是文献描述符, exec n>&m 关联所有n输出到m 重定向输入来自另一种文献描述符 格式为: n<&m n和m都是文献描述符 exec n<&m 关联所有n输入到m 关闭文献描述符 exec n>- [3] 六、操作文献属性 命名管道 mkfifo file 在这里,file是给于该管道文献名。 SUID 和 SGID SUID 当你执行一种设立了SUID位程序时,你就继承了该程序属主权限,而没有设立SUID位程序在执行时只拥有执行该程序顾客权限。 SGID 设立了SGID位程序将以程序属主所属顾客组权限来执行。 如果一种目录设立了SGID位,任何加到该目录下新文献自动继承该目录组,来代替生成文献顾客组。 SUID 和 SGID 位以字母s和S来表达。如果文献SUID或SGID权限被激活,SUID位就在文献属主执行权限位。 e.g. ls –l /usr/bin/passwd -r-sr-xr-x 1 root bin 19031 Feb 7 13:47 /usr/bin/passwd* 如果大写字母S代替了小写字母s,则表达该文献属主执行位没有被激活。 粘滞位 如果目录粘滞位被设立,则只有当你是如下顾客时,文献才干被删除: 设立粘滞位目录属组 要被删除文献属组 超级顾客root 粘滞位以字母t和T表达。如果大写字母代替了小写字母s,则表达该文献属主执行位没有被激活。 chmod e.g. chmod go-w,a+x a.out e.g. chmod –R o+r pub 变化pub目录及其子目录下所有文献权限 使用8进制办法设立SUID和SGID位时,把这些位数值放在原则权限位前面,SUID和SGI分别取数字4和2。 e.g. chmod 2444 * [4] 七、进程 切换前台进程到后台 bg e.g. bg %2 切换2号任务进程到后台 切换后台进程到前台 fg e.g. fg %2 切换2号后台任务进程到前台 保持后台进程 nohup e.g. nohup ls & 等待后台进程结束 wait 此命令会等待所指定任务或者进程执行完毕。 wait命令有3种形式:无选取(缺省) 等待所有进程结束, 通过进程ID e.g. wait 15060 等待15060进程结束 通过百分号%作为前缀任务号 e.g. wait %2 等待2号任务 显示后台任务 jobs 该命令显示哪些进程被悬挂,哪些在后台运营。 e.g. jobs [3] + Running first_one & [2] – Stopped (SIGTSTP) second_one [1] Stopped (SIGTTIN) third_one & 任务3正在运营;任务2是一种前台进程,被Ctrl+Z进行悬挂;任务1是一种后台进程,正在等待键盘输入 列出所有运营进程 ps UID 进程所有者; PID 进程标记符 ;PPID 父进程标记符;C 进程CPU占用率 STIME 进程开始时间; CMD 开始进程命令 关闭进程 kill e.g. kill %1 关闭任务号为1进程 subshell 概念 当你运营一种shell脚本时候,除了脚本中命令之外,另一种shell解释器拷贝也会产生。设个新shell被称为subshell。 覆盖当迈进程 exec 该命令可以用一种新进程来覆盖当迈进程。使用时要务必小心!!! 可以exec来彻底更改你shell解释器而不需要此外产生subshell。 e.g. exec csh 第二某些 SHELL编程 [5] 八、变量 标量变量 一次只能被赋予一种值 变量名 只能包括字母、数字和下划线 _ 。只能以字母或下划线作为开始。 变量值 可以存储或分派任何值到变量中。 带空格变量值需要用单引号或双引号引起来。 E.g. ¥ FRUIT=”apple orange plum” 访问变量 要获取变量值,只要在变量名之前加上美元符号$作为前缀即可 建立数组变量 办法一: 直接给一种索引赋值,格式为 name[index]=value e.g. $ FRUIT[0]=apple ;FRUIT[1]=banana ;FRUIT[2]=orange 办法二:在 ksh中为 set –A name value1 value2 … valueN e.g. $ set –A band derri terry mike gene 在bash中为 name=(value1 … valueN) e.g. $ band=(derri terry mike gene) 在bash中设定多重数组元素,需要在赋值之前建立一种数组索引: e.g. $ myarray=([0]=derri [3]=gene [2]=mike [1]=terry) 数组索引不必安装顺序 注意:索引必要是一种整数 如果一种数组变量名和一种已经被定义了标量变量名重名,那么标量变量值就变成了数组变量中索引0值。 访问数组值 办法为: ${name[index]} e.g. $ echo ${FRUIT[2]} 使用 ${name[*]} 和 ${name[@]} 可以访问数组中所有项目 ${name[*]}以为实际有几种索引就与否几项 ${name[@]}以为实际有几种索引项加上空格分开项目 e.g. $ FRUIT=(apple banana “orange passion”) ${name[*]}以为有3项 ${name[@]}以为有4项 只读变量 readonly 变量可以通过readonly命令被标记为只读.可用来标记数组或标量变量为只读 e.g. $ FRUIT=kiwi ;readonly FRUIT 删除变量 unset 格式: unset name e.g. $ unset FRUIT 只读变量是无法被删除,它将始终保持到shell退出为止。 输出环境变量 办法一: name=value ;export name 办法二: export name=value shell 变量 是在shell初始化时被设定并内部运用变量。 附录:惯用shell变量 $PWD 指出当前工作目录 $UID 指出当前顾客数字顾客标示符 $SHLVL 每次bash打开一种历程就自动加1,这个变量作用在于拟定内建exit命令与否关闭了当前会话。 $REPLY 若不给定参数,会让read命令读到输入最后一行 $RANDOM 产生0到32767随机数 $SECONDS 返回shell启动秒数。 $IFS shell使用该变量IFS值把一种字符串分隔为单独词。IFS默认设立是空格和tab键. e.g. dirs() { OLDIFS=”$IFS” IFS=: for I in $_DIR_STACK do echo “$I \c” done echo IFS=”$OLDIFS” } $PATH 搜索途径 $HOME 当前顾客主目录。 附录:特殊变量 $? 上一条命令退出状态保存在变量$?中,为0表达到功,非0表达失败可以用变化量来检测 一条命令与否执行成功。 e.g. if [ $?–eq 0 ] ;then echo “Command was successful.”; else echo “An error was encountered.” exit fi $- 专用变量$-是一种包括所有shell选项列表。检查$-与否包括字母i是判断shell是运营在交互模式下还是非交互模式下最简便办法。 e.g. case $- in *i*) PS1=”’uname –n’$ “ PATH=”$PATH:$HOM#/bin” Export PS1 PATH;; Esac $PS3 变化脚本运营提示符 e.g PS3=”New prompt” ;export PS3; 注意shell变量PS3把空格也作为最后一种字符。 [6] 九、置换 元字符* 匹配0到各种任意字符 匹配一种前缀 cmd prefix* 匹配一种后缀 cmd *suffix 匹配前缀和后缀 cmd prefix*suffix 元字符? 匹配1个任意字符 如果shell不能发现任何文献名可以匹配包括一种?元字符表达式,shell就会把?看作文献名中字符。由于这个因素,如果一种shell脚本使用匹配文献名作为参数,则需要验证文献与否存在,以免出错。 匹配字符集合 cmd [char] 匹配字符范畴 e.g. ls ch0[0-9].doc ;ls [a-zA-Z]* 取消一种集合,即不涉及一种集合 ! cmd [!char] e.g. $ ls [!a]* 列出不以a开头文献名 高档变量置换 有两大类高档变量置换: 1、 当一种变量获得一种值时,发生动作 2、 当一种变量失去一种值时,发生动作 名称 语法 描述 缺省值置换 ${param:-word} 如param值为空或未赋值,word取代param,但param值不变 缺省值赋值 ${param:=word} 如param值为空或未赋值,word被赋给param 空值错误 ${param:?msg} 如param值为空或未赋值,将msg信息输出到STDERR,并退出shell 有值置换 ${param:+word} 如param有值,word取代param值,但param值不变 e.g. FRUIT=${MYFRUIT:-APPLE} 命令置换 (用反引号 `) `command` shell执行命令集合,然后将命令输出成果置换。注意使用是反引号` e.g. UP=`date ;uptime` e.g. grep `id –un` /etc/passwd 算式置换 $((exp)) exp为一种数学表达式,可以使用/ * - + ()。 返回值不是四舍五入;在小数点后任何值都会被丢弃。 e.g. $ echo $(( ((5+3*2)-4)/2 )) 注意 最前面2个左括号中不可有空格,最背面2个有括号中也不可有空格。 [7] 十、引用 关闭对特殊字符含义解析解决被称为引用 需要引用解决元字符如下: * ? [ ] ‘ “ \ $ ;& ( ) |^ !# 使用反斜线 \ 使用反斜线 \可以使一种特殊字符被引用 e.g. echo A:\\ is my floppy drive 使用单引号 ‘ 在字符串先后使用单引号,可以使整个字符串被引用 单引号必要成对浮现 e.g. echo ‘<-$1250.**>;(update?) [Y|N]’ 使用双引号 “ 禁止除了$和’以外所有元字符。因而可以引用变量。 双引号中反斜线可以起作用,只在下面4个符号之前起作用 $ ‘ “ \ 引用解决换行以在下一行中继续 e.g. echo 12345\ >67890 输出为 e.g. echo ‘Line 1 >Line 2’ 输出为 Line1 Line2 引用解决正则表达式通配符 e.g. grep ‘[0-9][0-9]*$’ report2 report7 注意:象find等命令,通配符必要使用单引号、双引号或反斜线进行引用解决,这样通配符才干传递给find而不会被shell将其扩展开。 [8] 十一、流控制 if语句 if语法 代码返回0表达真,而非0为假。语法如下: if list1 then list2 elif list3 then list4 else list5 fi 也可写成一行: if list1 ;then list2 ;elif list3 ;then list4 ;else list5 ;fi ; 常用错误 在单行形式中 then语句前面忽视了分号 使用test 文献测试 语法: test option file 或 [ option file ] option为下表中一种选项, file 是一种文献或目录名字 选项 描述 -b file 当file存在并且是块文献时返回真 -c file 当file存在并且是字符文献时返回真 -d pathname 当pathname存在并且是目录时返回真 -e pathname 当由pathname指定文献或目录存在时返回真 -f file 当file存在并且是正规文献时返回真 -g pathname 当由pathname指定文献或目录存在并且设立了SGID位时返回真 -h file 当file存在并且是符号联接时返回真 -k pathname 当由pathname指定文献或目录存在并且设立了粘滞位时返回真 -p file 当file存在并且是命名管道时返回真 -r pathname 当由pathname指定文献或目录存在并且可读时返回真 -s file 当file存在并且是文献大小不不大于0时返回真 -u pathname 当由pathname指定文献或目录存在并且设立了SUID位时返回真 -w pathname 当由pathname指定文献或目录存在并且可写时返回真 -x pathname 当由pathname指定文献或目录存在并且可执行时返回真 -o pathname 当由pathname指定文献或目录存在并且被当迈进程有效顾客ID所指定顾客所拥有时返回真 字符串比较 检查字符串与否为空 –n -z 语法: test -z str 或 [ -z str ] str 是要检测字符串。当str长度为0时返回真。 语法: test -n str 或 [ -n str ] str 是要检测字符串。当str长度为非0时返回真。 e.g. if [ -z “$FRUIT_BASKET”] ;then echo “Your fruit basket is empty” else echo “Your fruit basket contains :$FRUIT_BASKET” fi 注意:str必要被引号括起来,否则str会被shell变量置换,而无法交给test。因此 这里为 [ -z “$FRUIT_BASKET”] 字符串相等 语法: test str1=str2 或 [ str1 = str2 ] e.g. if [ “$portmap” = “YES” ] ;then … if [ X$portmap =X“YES”] ;then … 注意上述2个例子都可以防止由于$portmap为空而报 字符串不等 语法: test str1 != str2 或 [ str1 != str2 ] e.g. if [ “$portmap” != “YES” ] ;then … if [ X$portmap !=X“YES”] ;then … 注意上述2个例子都可以防止由于$portmap为空而报错 数字比较 语法: test int1 op int2 或 [ int1 op int2 ] int1和int2可以是任何正整数或负整数,op为下表中一种操作符。如果int1或int2是一种字符串而不是整数,它就被作为0来对付。 操作符 描述 int1 –eq int2 如果int1等于int2,返回真。 也可用 = 符号 int1 –ne int2 如果int1不等于int2,返回真 int1 –lt int2 如果int1不大于int2,返回真 int1 –le int2 如果int1不大于等于int2,返回真 int1 –gt int2 如果int1不不大于int2,返回真 int1 –ge int2 如果int1不不大于等于int2,返回真 上一条命令退出状态保存在变量$?中,为0表达到功,非0表达失败可以用变化量来检测 一条命令与否执行成功: e.g. if [ $?–eq 0 ] ;then echo “Command was successful.”; else echo “An error was encountered.” exit fi 复合表达式 用内建操作符创立复合表达式 语法: test expr1 op expr2 或 [ expr1 op expr2 ] expr1 和 expr2 是任何有效test表达式,op为-a 或 -o。 expr1 –a exprt2 表达 expr1 和 expr2都为真时返回真 expr1 –o exprt2 表达 expr1 或 expr2都为真时返回真 用条件操作符创立复合表达式 语法: test expr1 op test expr2 或 [ expr1 ] op [ expr2 ] expr1 和 expr2 是任何有效test表达式,op为 && 或 ||。 && 表达 expr1 和 expr2都为真时返回真 || 表达 expr1 或 expr2都为真时返回真 使用条件操作符能提高效率,推荐使用。 否定一种表达式 语法: test !expr 或者 [!expr ] expr是任何有效test表达式 case语句 语法如下: case word in pattern1) list1 ;; pattern2) list2 ;; … patternN) listN ;; esac 或 case word in pattern1) list1 ;; … patternN) listN ;; esac e.g. case $- in *i*) PS1=”’uname –n’$ “ PATH=”$PATH:$HOM#/bin” Export PS1 PATH;; Esac 专用变量$-是一种包括所有shell选项列表。检查$-与否包括字母I是判断shell是运营在交互模式下还是非交互模式下最简便办法。 [9] 十二、循环 while循环 while循环语法 while cmd do list done 或 while cmd ;do list ;done 这里,cmd表达一种单一命令(普通是test表达式),而list表达一种或各种命令列表。 执行环节:1、执行cmd。 2、如cmd退出状态为非0,则退出循环。 3、如cmd退出状态为0,则执行list。 4、当list结束时,回到第一步 应用:while合法顾客输入 RESPONSE= while [ -z “$RESPONSE” ] ; do echo “Enter the name of a directory where your files are located:” read RESPONSE if [!–d “RESPONSE” ] ;then echo “ERROR:please enter a directory pathname. “ RESPONSE= Fi done 应用:输入重定向和while结合,从文献中一次读出一行 语法如下: while read LINE do :# manipulate file here done < file while和子shell间变量传递 ????????? 当while循环结束时,循环内变量不被保存。解决办法是当进入循环时重定向STDIN指针,然后在结束时恢复STDIN。语法如下: exec n<&0 < file while read LINE do :# manipulate file here done exec 0<&n n<&- 这里,n是一种不不大于2整数,file是你想要读取文献名。 e.g. 构造一种cat命令shell版本,如下所示: #!/bin/sh if [ “$#” –ge 1 ] ;then for FILR in $@ do exec 4<&0 < “$FILE” while read LINE ;do echo $ LINE ;done exec 0<&4 4<&- done fi until 循环 while循环非常适合于当某条件为真时执行命令;而until适合执行命令,直到条件为真。 until循环相称于用!操作符对cmd成果取反while循环。不推荐使用。 until语法 until cmd do list done for循环 for循环语法 for name in word1 word2 … wordN do list done 或 for name in word1 word2 … wordN ;do list ;done for循环用于使你能对列表中每一项重复执行一系列命令。 select循环 select循环提供了一种简朴方式来创立一种顾客可选取有限菜单。 select 循环语法 select name in word1 word2 … wordN do list done 循环控制 break命令 break命令表达退出当前循环。 break命令也可以接受一种整数作为参数,不不大于等于1整数,标记着退出循环层数。 e.g. 例如有3层循环。break 2 表达退出2层;break 3则退出3层。 continue命令 退出循环当前重复过程,而不是整个循环。 [10] 十三、参数 特殊shell变量 $0 $n $# $* $@ $?$$ $! 变量 描述 $0 被执行命令名字。 对于shell脚本来说,这就是调用它途径。 $n 这些变量相应是被一种脚本调用参数。这里n是一种十进制正数,相应是参数位置。 e.g. 第一种参数是$1,第二个参数是$2,以此类推。 $# 脚本支持参数个数 $* 所有参数被双重引用。如果脚本接受到两个参数,$*等于$1 $2 $@ 所有参数都被独立地双重引用。如果一种脚本接受到两个参数,$*等于$1 $2 $? 最后一种被执行命令退出状态。 $$ 当前shell进程号。对于shell脚本来说,这就是她们执行进程号。 $! 最后一种后台命令进程号。 shift命令 语法: shift [n] After a shift n,all parameters in $* are moved to the left n positions,and $# is decremented by n. The default for n is 1.The shift command does not affect the positional parameter 0. basename 命令basename获得一种文献或者目录绝对或者相对途径,仅仅返回该途径下面文献或目录名。 e.g. #!/bin/sh case `basename $0` in listtar) TARGS=”-tvf $1”;; maketar) TARGS=”-cvf $1.tar $1”;; *) echo “Usaged:$0 [file|directory]” exit 0 ;; esac tar $TARGS 仿效basename(用于没有basename命令系统)脚本 #!/bin/sh if [ -n “$1”] ;then echo “$1” | sed –e ‘s/^.*\///’ else echo “Usage:basename [file] “ 1>&2 exit 1 fi exit 0 检查变元数目与否与规定数目匹配 $#应用举例 #!/bin/sh USAGE=”Usage:`basename $0` [-c|-t] [file|directory]” If [ $# -lt 2] ;then echo “$USAGE” exit 1 fi case “$1” in -t) TARGS=”-tvf $2” ;; -c) TARGS=”-cvf $2.tar $2” ;; *) echo “$USAGE” exit 0 ;; esac tar $TARGS $*和$@区别 为shell脚本指定变元被存在两个特殊变量$*和$@中。这两个变量之间差别在于如何存储变元: $*不保存引用,而$@则保存。 getopts命令 getopts语法格式如下: getopts option-string var 这里option-string是一种字符串,它涉及了getopts所应当考虑所有单个选项字符。var是该选项应当被设立变量名字。推荐,var处用一种名为OPTION变量。 getopts对命令行中给出选项进行解析环节如下: 1 getopts检查所有命令行参数,查找以 – 字符开头参数。 2 当发现一种以 – 字符开头参数时,它比较 – 之后紧接着字符与给定 option-string中所有字符。 3 如果发现该字符在 option-string中有匹配,则把该选项字符赋予变量var;否则,var值设立为?字符。 4 重复 1~3,直到命令行中给出所有选项都被检查完。 5 当完毕后,getopts返回一种非0退出码。此外,它将变量OPTIND值设立为最后一种参数下标。 getopts可以指出哪些选项规定附带参数 通过在选项背面附加一种冒号 :字符来实现。在这种状况下,解析一种选项后,附带参数就会设立为变量OPTARG值。 getopts举例 脚本如下: #!/bin/sh USAGE="Usage:`basename $0` [-v] [-f] [filename] [-o] [filename]"; VERBOSE=false while getopts f:o:v OPTION: do case "$OPTION" in f) INFILE="$OPTARG";; o) OUTFILE="$OPTARG";; v) VERBOSE=true;; \?) echo "$USAGE" exit 1 ;; esac done shift 'echo "$OPTIND -1"|bc' if [ -z "$1" ] && [ -z "$
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服