1 .shell编程1~5

Posted 皓月天边 半步青莲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1 .shell编程1~5相关的知识,希望对你有一定的参考价值。

 

 

 

 

Shell编程

如今,不会Linux的程序员都不意思说自己是程序员,而不会shell编程就不能说自己会Linux。说起来似乎shell编程很屌啊,然而不用担心,其实shell编程真的很简单。

一.背景

1.1.什么是shell编程

高大上的解释,往往让人摸不住头脑。一句话概括就是:shell编程就是对一堆Linux命令的逻辑化处理。

Shell是操作系统的最外层, Shell可以合并编程语言以控制进程和文件,以及启动和控制其它程。shell通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出来管理您与操作系统之间的交互。简单来说Shell就是一个用户跟操作系统之间的一个命令解释器。

Shell是用户与 Linux操作系统之间沟通的桥采。用户可以输入命令执行,又可以利用Shell脚本编程去运行。

 

1.2 为什么要会shell编程

举个简单的例子,我们做javaweb开发的,在以前,如果要在本地将程序打包,然后部署到远程服务器(抛开现在的ci, 原始的方法), 我们以前的做法通常会经历如下几个步骤:

  • 拉取最新代码(git pull)

  • 编译打包

  • 上传并部署到远程服务器

每次打包都要经历这一个阶段,效率低又烦躁。而此时,我们可以编写一个shell脚本,然后每次只需要运行一下这个shell脚本,即可实现打包部署这一系列动作,彻底解放双手,多好

 

1.3 Linux shell的分类

Linux Shell种类非常多,常见的有: Bourne Shell(usr/bin/sh或/bin/sh)、 Bourne Again Shell(/bin/bash)、

C Shell(/usr/bin/csh),K Shell (/usr/bin/ksh),Shell for Root(/sbin/sh)等。不同的Shell语言的语法有所不同,所以不能交换使用。

最常用的 shell是Bash,也就是 Bourne Again Shell,由于易用和免费,Bash在日常工作中被广泛使用,也是大多数 Linux系统默认的Shell。

接下来我们条写一个简单的shell本。(shell脚本一般文件名以.sh结尾,同时文件第一行定义该脚本为shell脚本)

 

1.4 bash查看
echo $BASH

  

 

 

 

二 .入门

2.1 第一个shell程序
vi first_shell.sh         //打开一个文件
  #!/bin/bash                //表明这是一个shell脚本
  ​
  #Filename:first_shell.sh   //这是一个注释,没有实际性的意义
  #auto echo hello world     //注释,脚本功能描述,自动打印"hello world" 的意思,没有实际性的意义
  #by authers kds 2020-4     //注释,作者,时间,没有实际性的意义
  echo "Hello World!"        //打印hello world
  mkdir -p /local/2020/04/   //mkdir -p :递归创建目录,即使上级目录不存在,会按目录层级自动创建目录

 


esc :退出编辑

wq :保存

 

2.2 测试脚本是否有问题

没有任何输出则表示脚本没问题

  sh  -n first_shell.sh 

2.3执行脚本
  chomd o+x first_shell.sh   //添加执行权限
  ./first_shell.sh           //运行

 

 

 

 

三.shell编程之变量详解

Shell编程语言是非类型的解释型语言,不像C++/JAVA语言编程时需要事先声明变量, shell给一个变量赋值,实际上就是定义了变量,在 Linux支持的所有shell中,都可以用赋值符号(=)为变景赋值。

shell变量可分为两类:局部变量和环境变量。局部变量只在创建它们的shell脚本中使用。而环境变量则可以在创建它们的 shell及其派生出来的任意子进程中使用。有些变量是用户创建的,其他的则是专用shel1变量。

例如在脚本里面定义A=123,定义这样一个变景,前面变量名,后面是变量的值。

3.1 引用变景可以使用$A,把变景放在脚本里面会出现什么样的效果呢?

如下:

vi test.sh

  #!/bin/bash                //表明这是一个shell脚本
  #Author kds 2020-4-27
  A=369
  echo "Printf variables equal is $A"   

 

执行脚本:

/usr/bin/bash first_shell.sh

结果会显示到:

Printf variables equal is 369

简单的理解变量,相当于定义一个别名-名称,引用的时候加上$符号就可以了。

 

假如定义变景 name= mayun

执行echo $name将会显示 mayun

3.2 shell常见的系统变量解析:

$0 当前程序的名称

$n 当前程序的第n个参数,n=1,2,…9

$* 当前程序的所有参数(不包括程序本身)

$# 当前程序的参数个数(不包括程序本身)

$? 命令或程序执行完后的状态,一般返回0表示执行成功(直接 echo $? 表示查看上一个命令是否执行成功)。

$UID 当前用户的ID

$PWD 当前所在的目录

vi auto_var.sh

  #!/bin/bash        
  #auto print variables
  #Author kds 2020-4-27
  #-e:激活转义字符。
  echo -e \'\\033[32m------------------\\033[0m\'  
  echo "This is $0 param !"
  echo "This  \\$1 is $1 param !"
  echo "This  \\$2 is $2 param !"
  echo -e \'\\033[32m------------------\\033[0m\'
  echo "This  \\$* is $* param !"
  echo "This  \\$# is $# param !"
  echo "This  \\$? is $? param !"
  echo

 

执行脚本:

sh auto_var.sh 11 36

 

 

 

3.3 编写一个简单的echo打印菜单

vi auto_httpd.sh

 
  #!/bin/bash
  #auto install httpd
  #Author kds 2020-4-27
  echo -e \'\\033[32m------------------\\033[0m\'  
  FILES=httpd-2.2.17.tar.bz2
  URL=http://mirrors.cnnic.cn/apache/httpd/
  PREFIX=/usr/local/apache2/
  echo -e \'\\033[36Please Select Install Menu\\033[0m\'  
  echo
  echo "1) 官方下载Httpd文件包。"
  echo "2) 解压apache源码包。"
  echo "3) 编译安装Http服务器。"
  echo "4) 启动Httpd服务器。"
  echo -e \'\\033[32m------------------\\033[0m\'  
  sleep 20

 


执行脚本:

sh auto_httpd.sh

 

 

四.shell编程之IF条件语句案列演练

在Linux Shell编程中,if,for,while,case等条件流程控制语句用的非常多,把这些学好,对提升脚本的功能有非常大的帮助。

下面将逐个来讲解具体的用法:

 

4.1 if条件判断语句

  
  if (表达式);then #if (Variable in Array) 
      语句1
  else
      语句2
  fi               #if语句结束
  ​
4.1.1 案列一

数字大小对比

vi auto_num.sh

 #!/bin/sh
  #author kds 2020-04-28
  NUM=100
  NUM1=200
  if(($NUM > $NUM1));then
      echo "this num $NUM greater $NUM1 !"
  else
      echo "this num $NUM little $NUM1 !"
  fi

 

4.1.2案列二

判断目录是否存在,不存在则新建(注意,中括号之间必须要空格)

vi auto_file.sh

 #!/bin/sh
  #author kds 2020-04-28
  #judge dir exist
  DIR=/data/20200411
  if [ ! -d $DIR ];then
          mkdir -p $DIR
          echo -e "\\033[32mThis $DIR Create success! \\033[0m"
  else
          echo -e "\\033[32mThis DIR is exists.Please exit ...! \\033[0m"
  fi
 

 

执行脚本:

sh -n auto_file.sh

sh auto_file.sh

4.1.3 案列三

判断文件是否存在,存在则打印内容,不存在则创建且往里面写入内容。

vi auto_files.sh

#!/bin/sh
  #author kds 2020-04-28
  #auto test files
  FILES=/tmp/test.txt
  ​
  if [ ! -f $FILES ];then
          echo "ok" >> $FILES     # 两个大于符号时追加,一个是覆盖
  else
          echo -e "\\033[32m---------------------!\\033[0m"
          cat $FILES
  fi

 

4.1.4 案列四

多个条件测试判断

vi auto_scores.sh

#!/bin/sh
  #author kds 2020-04-28
  #auto test scores
  scores=$1
  if [ -z $scores ];then          # 为空则退出
      echo "Usage:{$0 60|80.}";
      exit;
  elif [[ $scores -gt 85 ]];then
      echo "very good!";
  elif [[ $scores -gt 75 ]];then
      echo "good!";
  elif [[ $scores -gt 60 ]];then
      echo "pass!";
  else
      echo "no pass!";
  fi;

 

执行脚本:

sh -n auto_scores.sh

sh auto_scores.sh

4.1.5 案列五

if条件综合Shell实战脚本编写:

通过if语句和之前变量的学习,今天我们将把我们所学的综合在一起来讲解一个实战运维脚本,一键安装LAMP环境的脚本:

一建源码安装LAMP脚本,先分解脚本的各个小功能:

打印菜单:

1)安装apache WEB服务器

2)安装mysql DB服务器

3)安装php 服务器

4)整合LAMP架构并启动服务

1、Apache服务器安装部署。

下载httpd-2.2.27.tar.gz版本,下载URL,解压,进入安装目录,configure;make ;make install

2、Mysql服务器的安装。

下载mysql-5.5.20.tar.bz2版本,下载URL,解压,进入安装目录,configure;make ;make install

3、PHP服务器安装。

下载php-5.3.8.tar.bz2版本,下载URL,解压,进入安装目录,configure;make ;make install

4、LAMP架构的整合和服务启动。

/usr/local/apache2/bin/apachectl start

vi htdocs/index.php

<?php

phpinfo();

?>

mysql的配置文件:vi /usr/local/mysql/my.conf


[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
replicate-ignore-db = mysql
replicate-ignore-db = test
replicate-ignore-db = information_schema
user = mysql
port = 3306
socket = /tmp/mysql.sock
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
log-error = /usr/local/mysql/mysql_error.log
pid-file = /usr/local/mysql/mysql.pid
open_files_limit = 65535
back_log = 600
max_connections = 5000
max_connect_errors = 1000
table_open_cache = 1024
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 600
#thread_concurrency = 8
query_cache_size = 128M
query_cache_limit = 2M
query_cache_min_res_unit = 2k
default-storage-engine = MyISAM
default-tmp-storage-engine=MYISAM
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 128M
max_heap_table_size = 128M
log-slave-updates
log-bin = /usr/local/mysql/binlog/binlog
binlog-do-db=oa_fb
binlog-ignore-db=mysql
binlog_cache_size = 4M
binlog_format = MIXED
max_binlog_cache_size = 8M
max_binlog_size = 1G
relay-log-index = /usr/local/mysql/relaylog/relaylog
relay-log-info-file = /usr/local/mysql/relaylog/relaylog
relay-log = /usr/local/mysql/relaylog/relaylog
expire_logs_days = 10
key_buffer_size = 256M
read_buffer_size = 1M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover
interactive_timeout = 120
wait_timeout = 120
skip-name-resolve
#master-connect-retry = 10
slave-skip-errors = 1032,1062,126,1114,1146,1048,1396
#master-host = 192.168.1.2
#master-user = username
#master-password = password
#master-port = 3306
server-id = 1
loose-innodb-trx=0
loose-innodb-locks=0
loose-innodb-lock-waits=0
loose-innodb-cmp=0
loose-innodb-cmp-per-index=0
loose-innodb-cmp-per-index-reset=0
loose-innodb-cmp-reset=0
loose-innodb-cmpmem=0
loose-innodb-cmpmem-reset=0
loose-innodb-buffer-page=0
loose-innodb-buffer-page-lru=0
loose-innodb-buffer-pool-stats=0
loose-innodb-metrics=0
loose-innodb-ft-default-stopword=0
loose-innodb-ft-inserted=0
loose-innodb-ft-deleted=0
loose-innodb-ft-being-deleted=0
loose-innodb-ft-config=0
loose-innodb-ft-index-cache=0
loose-innodb-ft-index-table=0
loose-innodb-sys-tables=0
loose-innodb-sys-tablestats=0
loose-innodb-sys-indexes=0
loose-innodb-sys-columns=0
loose-innodb-sys-fields=0
loose-innodb-sys-foreign=0
loose-innodb-sys-foreign-cols=0


slow_query_log_file=/usr/local/mysql/mysql_slow.log
long_query_time = 1
[mysqldump]
quick
max_allowed_packet = 32M

 

 

 vi auto_lamp.sh内容如下:


#!/bin/bash
#auto install LAMP
#by kds 2020-04-30
#Httpd define path variable
H_FILES=httpd-2.4.43.tar.bz2
H_FILES_DIR=httpd-2.4.43
H_URL=http://mirrors.cnnic.cn/apache/httpd/
H_PREFIX=/usr/local/apache2/


#MySQL define path variable
M_FILES=mysql-5.6.15.tar.gz
M_FILES_DIR=mysql-5.6.15
M_URL=http://dev.mysql.com/get/Downloads/MySQL-5.6/
M_PREFIX=/usr/local/mysql/


#PHP define path variable
P_FILES=php-5.3.28.tar.bz2
P_FILES_DIR=php-5.3.28
P_URL=http://mirrors.sohu.com/php/
P_PREFIX=/usr/local/php5/



echo -e \'\\033[32m-----------------------------\\033[0m\'
echo


if [ -z "$1" ];then


echo -e "\\033[36mPlease Select Install Menu follow:\\033[0m"
echo -e "\\033[32m1)编译安装Apache服务器\\033[1m"
echo "2)编译安装MySQL服务器"
echo "3)编译安装PHP服务器"
echo "4)配置index.php并启动LAMP服务"
echo -e "\\033[31mUsage: { /bin/sh $0 1|2|3|4|help}\\033[0m"
exit
fi


if [[ "$1" -eq "help" ]];then
echo -e "\\033[36mPlease Select Install Menu follow:\\033[0m"
echo -e "\\033[32m1)编译安装Apache服务器\\033[1m"
echo "2)编译安装MySQL服务器"
echo "3)编译安装PHP服务器"
echo "4)配置index.php并启动LAMP服务"
echo -e "\\033[31mUsage: { /bin/sh $0 1|2|3|4|help}\\033[0m"
exit
fi
######################################
#Install httpd web server
if [[ "$1" -eq "1" ]];then


wget -c $H_URL/$H_FILES && tar -jxvf $H_FILES && cd $H_FILES_DIR && ./configure --prefix=$H_PREFIX --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util
if [ $? -eq 0 ];then
make && make install
echo -e "\\n\\033[32m-----------------------------------------------\\033[0m"
echo -e "\\033[32mThe $H_FILES_DIR Server Install Success !\\033[0m"
else
echo -e "\\033[32mThe $H_FILES_DIR Make or Make install ERROR,Please Check......"
exit 0
fi
fi


#Install Mysql DB server
if [[ "$1" -eq "2" ]];then
echo -e "\\033[32m安装编译工具及依赖库!\\033[0m"
yum -y install gcc gcc-c++ make autoconf libtool-ltdl-devel gd-devel freetype-devel libxml2-devel libjpeg-devel libpng-devel openssl-devel curl-devel bison patch unzip libmcrypt-devel libmhash-devel ncurses-devel sudo bzip2 flex libaio-devel
wget -c $M_URL/$M_FILES && tar -xzvf $M_FILES && cd $M_FILES_DIR
#安装cmake 编译器
&& yum install cmake -y ;
echo "======> 安装前的设置 <======";
cmake .
-DCMAKE_INSTALL_PREFIX=$M_PREFIX \\
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \\
-DDEFAULT_CHARSET=utf8 \\
-DDEFAULT_COLLATION=utf8_general_ci \\
-DWITH_EXTRA_CHARSETS=all \\
-DWITH_MYISAM_STORAGE_ENGINE=1 \\
-DWITH_INNOBASE_STORAGE_ENGINE=1 \\
-DWITH_MEMORY_STORAGE_ENGINE=1 \\
-DWITH_READLINE=1 \\
-DWITH_INNODB_MEMCACHED=1 \\
-DWITH_DEBUG=OFF \\
-DWITH_ZLIB=bundled \\
-DENABLED_LOCAL_INFILE=1 \\
-DENABLED_PROFILING=ON \\
-DMYSQL_MAINTAINER_MODE=OFF \\
-DMYSQL_DATADIR=/usr/local/mysql/data \\
-DMYSQL_TCP_PORT=3306
echo "======> 设置成功!开始编译安装,大约需要20分钟,耐心等待...<======";
make && make install

if [ $? -eq 0 ];then
echo -e "\\n\\033[32m======> 编译成功!开始设置组和用户! <======\\033[0m"
sleep 2s
groupadd mysql &&
useradd mysql -g mysql -M -s /sbin/nologin &&
chown mysql:mysql /usr/local/mysql/
echo "======> 制作服务启动,注册服务 <======";
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
echo "======> 使用默认配置文件 <======";
cp /usr/local/mysql/my.conf /etc/my.conf
chmod 755 /etc/init.d/mysqld
echo "======>让chkconfig管理mysql服务! <======";
chkconfig --add mysqld
echo "======> 开机启动! <======";
chkconfig mysqld on
echo "======> 初始化mysql <======";
/usr/local/mysql/scripts/mysql_install_db --defaults-file=/usr/local/mysql/my.conf --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data &
echo "======> 关闭mysql服务 <======";
service mysqld stop
if [ $? -eq 0 ]; then
echo "======> mysql服务关闭成功! <======";
else
echo "======> mysql服务关闭失败! <======";
exit;
fi
echo "======> 配置环境变量 <======";
echo "export PATH=$PATH:/usr/local/mysql/bin/" >> /etc/profile
source /etc/profile
echo "======>启动mysql服务 ======>";
service mysqld start
if [ $? -eq 0 ]; then
echo "======> mysql服务开启成功! <======";
else
echo "======> mysql服务开启失败! <======";
exit;
fi
echo -e "\\n\\033[32m
以下部分如有必要,请手动完成
1.查看mysql版本
/usr/local/mysql/bin/mysql --version
2 设置root密码为: “123456” ,默认无密码
/usr/local/mysql/bin/mysqladmin -u root password "123456"
||SET PASSWORD FOR \'用户名\'@\'主机\' = PASSWORD(‘密码\');
3.授权远程登陆
grant all privileges on *.* to root@\'%\' identified by \'123456\';
flush privileges;
\\033[0m"
exit;

else
echo -e "\\033[32m编译失败!,请检查......"
exit 0
fi
fi


#Install PHP server
if [[ "$1" -eq "3" ]];then


wget -c $P_URL/$P_FILES && tar -jxvf $P_FILES && cd $P_FILES_DIR &&./configure --prefix=$P_PREFIX --with-config-file-path=$P_PREFIX/etc --with-mysql=$M_PREFIX --with-apxs2=$H_PREFIX/bin/apxs
if [ $? -eq 0 ];then
make ZEND_EXTRA_LIBS=\'-liconv\' && make install
echo -e "\\n\\033[32m-----------------------------------------------\\033[0m"
echo -e "\\033[32mThe $P_FILES_DIR Server Install Success !\\033[0m"
else
echo -e "\\033[32mThe $P_FILES_DIR Make or Make install ERROR,Please Check......"
exit 0
fi
fi
####################################


if [[ "$1" -eq "4" ]];then


sed -i \'/DirectoryIndex/s/index.html/index.php index.html/g\' $H_PREFIX/conf/httpd.conf
$H_PREFIX/bin/apachectl restart
echo "AddType application/x-httpd-php .php" >>$H_PREFIX/conf/httpd.conf
IP=`ifconfig eth1|grep "Bcast"|awk \'{print $2}\'|cut -d: -f2`
echo "You can access http://$IP/"


cat >$H_PREFIX/htdocs/index.php <<EOF
<?php
phpinfo();
?>
EOF
Fi


4.2 逻辑运算符解析:
4.2.1 文件测试:
  • -f:判断文件是否存在 eg: if [ -f filename ]

  • -d:判断目录是否存 eg: if [ -d dir ]

  • -e:测试文件或目录是否存在(Exist);

  • -r:测试当前用户是否有权限读取(Read);

  • -w:测试当前用户是否有权限写入(Write);

  • -x:测试是否设置有可执行(Excute)权限;

 

4.2.2 整数值比较
  • -eq:第一个数等于(Equal)第二个数;

  • -ne:第一个数不等于(Not Equal)第二个数;

  • -gt:第一个数大于(Greater Than)第二个数;

  • -lt:第一个数小于(Lesser Than)第二个数;

  • -le:第一个数小于或等于(Lesser or Equal)第二个数;

  • -ge:第一个数大于或等于(Greater or Equal)第二个数;

  • -a : 双方都成立(and) 逻辑表达式 -a 逻辑表达式

  • -o : 单方成立(or) 逻辑表达式 -o 逻辑表达式

整数值比较在Shell脚本编写中的应用较多。例如,用来判断已登录用户数量、开启进程数、磁盘使用率是否超标,以及软件版本号是否符号要求等。实际 使用时,往往会通过变量引用、命令替换等方式来获取一个数值。

 

4.2.3 字符串比较:
  • =:第一个字符串与第二个字符串相同。

  • !=:第一个字符串与第二个字符串不相同,其中 “ !”表示取反。

  • -z:检查字符串是否为空,对于未定义或赋予空值的变量将是为空串。

 

4.2.4 逻辑测试:
  • &&:逻辑与,表示“而且”,只有当前后两个条件都成立时,整个测试命令的返回值才为0(结果成立),使用test命令测试时,“&&”可以使用“-a”代替。

  • ||:逻辑或,表示“或者”,只要前后两个条件有一个成立,整个测试命令返回的值即为0(结果成立)。使用test命令测试时可以使用“-o”代替。

  • !:逻辑否,表示“不”,只有当条件不成立时,整个测试命令返回的值才为0(结果成立)。

     

五 .使用if条件语句编写MySQL备份脚本

5.1 自动备份Mysql数据库脚本

vi auto_backup_mysql.sh

 
  #!/bin/sh
  #author kds 2020-04-28
  #auto backup mysql
  ​
  #Define PATH 定义变量
  BAKDIR=/data/backup/mysql/`date +%Y%m%d` #以日期命名
  MYSQLDB=webapp
  MYSQLPW=backup
  MYSQLUSR=backup
  MYSQLCMD=/usr/bin/mysqldump
  ​
  #must use root user run scripts 必须使用root用户运行,$UID为系统变量
  if [$UID -ne 0];then
      echo This script must use the root user!!!
      sleep 2
      exit 0
  fi
  ​
  #Define DIR and mkdir DIR 判断目录是否存在,不存在则创建
  if [ !-d $BAKDIR ];then
      mkdir -p $BAKDIR
      echo -e "\\033[32mThe $BAKDIR Create is Successfully!\\033[0m"
  else
      echo This is $BAKDIR exists...
  fi
  ​
  #Use mysqldump backup mysql 使用mysqldump备份数据库
  $MYSQLCMD -u$MYSQLUSR -p$MYSQLPW -d $MYSQLDB >$BAKDIR/discuz.sql
  echo "The mysql backup successfully"
  if [ $? -eq 0 ];then
      echo -e "\\033[32mThe Mysql Backup $MYSQLDB Successfully!\\033[0m"
  else
      echo -e "\\033[32mThe Mysql Backup $MYSQLDB Failed.Please check!\\033[0m"
  fi
  ​

 

5.2 linux定时任务

定时执行某个脚本

crontab -e

  
# 此时会进入 vi 的编辑画面让您编辑工作!注意到,每项工作都是一行。
#分 时 日 月 周     |<==============任务的完整命令行
* * * * *       /home/blue/do/rsyncfile.sh

内容:

  
#0 23 * * * /root/scripts/login_day.sh
*/2 * * * * /home/test/first_shell.sh >> /home/test/log_test.log

添加执行权限:chmod +x /home/test/first_shell.sh

重启下cron :service crond restart

查看定时任务是否执行:两分钟执行一次

 

 

 

 

 

以上是关于1 .shell编程1~5的主要内容,如果未能解决你的问题,请参考以下文章

1 .shell编程1~5

1 .shell编程1~5

代码片段:Shell脚本实现重复执行和多进程

Linux bash基础特性二

Android 实用代码片段

Android 实用代码片段