class12 shell編程(四)軟件包管理(二)

一、shell編程(四)

1、循環特殊用法

while 循環的特殊用法(遍歷文件的每一行):
while read line; do
      循環體
  done < /PATH/FROM/SOMEFILE
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line
雙小括號方法,即((…))格式,也可以用于算術運算
雙小括號方法也可以使bash Shell 實現C語言風格的變量操作    #I=10
    #((I++))
for 循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))do
   循環體done控制變量初始化:僅在運行到循環代碼段時執行一次
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而后再做條件判斷

select 循環與菜單

select: select NAME [in WORDS ... ;] do COMMANDS; done       
select variable in list
    do
       循環體命令
    doneselect 循環主要用于創建菜單,按數字順序排列的示菜單項將顯示在標準錯誤上,并顯示PS3提示符,等待用戶輸入                 
 PS3="would you like ?"用戶輸入菜單列表中的某個數字,執行相應的命令                    
用戶輸入被保存在內置變量 REPLY 中。
注意:select循環為死循環
                 
[root@6 cd]# select name in a b c d;do echo "you choose is $name"; done
    1) a
    2) b
    3) c
    4) d
    #? 3
    you choose is c
    #? 2
    you choose is b
    #? 
[root@6 bin]#PS3="would you like ?"  
[root@6 bin]# select name in a b c d;do echo "you choose is $name"; done
1) a
2) b
3) c
4) d
would you like ?2
you choose is b

select與case

select 用是個無限循環,因此要記住用 break  命令退用出循環,或用 exit 按 命令終止腳本。也可以按 ctrl+c退出循環。
break #和continue #;
break #:退出#層循環continue #:跳過#次循環
  select和經常和case聯合使用
與 for循環類似,可以省略 in list,此時使用位置參量            
#! /bin/bash PS3="would you like ?"select choose in a b c d;do
 case   $choose in
 a)   echo "THIS IS A PART."
    ;;
 b)   echo "THIS IS B PART."
    ;;
 c)   echo "THIS IS C PART."
    ;;
 d)   echo "THIS IS D PART."
    ;;
 *)    break
    ;; esacdone

2、函數介紹

函數function是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程。   
                        
優先級:alias》函數》內部命令》外部命令
    
它與shell程序形式上是相似的,不同的是它不是一個單獨的進程,不能獨立運行,而是shell 程序的一部分。       
函數和shell程序比較相似,區別在于:Shell 程序在子Shell中運行
而Shell函數在當前Shell中運行。因此在當前Shell 中,函數可以對shell 中變量進行修改

定義函數

函數由兩部分組成:函數名和函數體。

語法一:    function f_name   {    ... 函數體...
    }
語法二:    function f_name()  {    ... 函數體...
    }
語法三:
    f_name  (){    ... 函數體...
    }

函數使用

函數的定義和使用:

可在交互式環境下定義函數
可將函數放在腳本文件中作為它的一部分
可放在只包含函數的單獨文件中

調用:函數只有被調用才會執行;
    調用:給定函數名
    函數名出現的地方,會被自動替換為函數代碼
函數的生命周期:被調用時創建,返回時終止

函數返回值

函數有兩種返回值:
函數的執行結果返回值:
    (1)使用echo 或printf 命令進行輸出
    (2) 函數體中調用命令的輸出結果
函數的退出狀態碼:
    (1)默認取決于函數中執行的最后一條命令的退出狀態碼
    (2)自定義退出狀態碼, 其格式為:    return 從函數中返回,用最后狀態命令決定返回值    return 0 無錯誤返回。    return 1-255 有錯誤 返回

交互式環境下定義和使用函數

示例:    $dir() {
    > ls -l
    > }
定義該函數后,若在$ 后面鍵入dir ,其顯示結果同ls -l的作用相同。    $dir該dir函數將一直保留到用戶從系統退出,或執行了如下所示的unset 命令:
    $ unset dir

在腳本中定義及使用函數

函數在使用前必須定義,因此應將函數定義放在腳本開始部分,直至shell 首次發現它后才能使用
調用函數僅使用其函數名即可。
示例:    $cat func1    #!/bin/bash
    # func1
    hello()
    {    echo "Hello there today's date is `date +%F`"
    }    echo "now going to the function hello"
    hello    echo "back from the function"

使用函數文件

可以將經常使用的函數存入函數文件,然后將函數文件載入shell。 

文件名可任意選取,但最好與相關任務有某種聯系。例如:functions.main

一旦函數文件載入shell,就可以在命令行或腳本中調用函數??梢允褂胹et 命令查看所有定義的函數,其輸出列表包括已經載入shell的所有函數。

若要改動函數,首先用unset 命令從shell中刪除函數。改動完畢后,再重新載入此文件。

創建函數文件

函數文件示例:    $cat functions.main    #!/bin/bash
    #functions.main
    findit()
    {    if [ $# -lt 1 ] ; then
    echo "Usage:findit file"
    return 1
    fi
    find / -name $1 –print
    }

載入函數

函數文件已創建好后,要將它載入shell

定位 函數文件 并載入shell 的格式:
.  filename 或 source filename

注意:此即< 點> < 空格> < 文件名>這里 的文件名要帶正確路徑

示例:上例中的函數,可使用 如下命令:
$ . functions.main

檢查載入函數

使用set命令檢查函數是否已載入。set 命令將在shell中顯示所有的載入函數 。

示例:    $set
    findit=( )
    {    if [ $# -lt 1 ]; then
    echo "usage :findit file";    return 1
    fi
    find / -name $1 -print
    }
    …

執行shell 函數

要執行函數,簡單地鍵入函數名即可 :
示例:    $findit groups
    /usr/bin/groups
    /usr/local/backups/groups.bak

刪除shell函數

現在對函數做一些改動。首先刪除函數,使其對shell 不可用。使用unset 命令完成此 功能.

命令格式為:unset function_name
實例:$unset findit
再鍵入set 命令,函數將不再 顯示

函數參數

函數可以接受參數:
    傳遞參數給函數:調用函數時,在函數名后面以空白分隔給定參數列表即可;例如“testfunc arg1 arg2 ...”
    
    在函數體中當中,可使用$1, $2, ...調用這些參數;還可以使用$@, $*, $# 等特殊變量

函數變量

變量作用域:
環境變量:當前shell和子shell 有效
本地變量:只在當前shell進程有效,為執行腳本會啟動專用子shell進程;因此,本地變量的作用范圍是當前shell腳本程序文件,包括腳本中的函數。
           
局部變量:函數的生命周期;函數結束時變量被自動 銷毀
               
注意:如果函數中有局部變量,如果其名稱同本地變量, 使用局部變量。
           
在函數中定義局部變量的方法     local NAME=VALUE

函數遞歸實例

函數遞歸:
    函數直接或間接調用自身
    注意遞歸層數
    
遞歸實例:
    階乘是基斯頓·于 卡曼于 1808 年發明的運算符號,是數學術語
    一個正整數的階乘(factorial)是所有小于及等于該數的正整數的積,并且有0 的階乘為1 。自然數n 的階乘寫作n!。 。    n!=1 ×2 ×3 ×... ×n。 。
    階乘亦可以遞歸方式定義:0!=1 ,n!=(n-1)! ×n。 。    n!=n(n-1)(n-2)...1    n(n-1)! = n(n-1)(n-2)!

函數 遞歸示例

示例: fact.sh#!/bin/bash#fact() {   if [ $1 -eq 0 -o $1 -eq 1 ]; thenecho 1
   elseecho $[$1*$(fact $[$1-1])]fi}
fact $1

二、軟件包管理(二)

包查詢

rpm {-q|--query} [select-options] [query-options]
[select-options]
-a:  所有包-f:  查看指定的文件由哪個程序包安裝生成[root@6 yum.repos.d]# rpm -qf /bin/rpmrpm-4.8.0-55.el6.x86_64              
-p rpmfile(包名):針對尚未安裝的程序包文件做查詢操作;  
 [root@6 cd]# rpm -qp /misc/cd/Packages/tree-1.5.3-3.el6.x86_64.rpm 
tree-1.5.3-3.el6.x86_64  
 
--whatprovides CAPABILITY :查詢指定的 CAPABILITY由哪個包所提供 [root@6 cd]# rpm -q --whatprovides rpm
  rpm-4.8.0-55.el6.x86_64
 
--whatrequires CAPABILITY :查詢指定的 CAPABILITY 被哪個包所依賴  [root@6 cd]# rpm -q --whatrequires rpm
rpm-libs-4.8.0-55.el6.x86_64
man-1.6f-32.el6.x86_64
rpm-python-4.8.0-55.el6.x86_64
yum-3.2.29-73.el6.centos.noarch
policycoreutils-2.0.83-29.el6.x86_64
python-meh-0.12.1-3.el6.noarch
 
rpm2cpio  包文件|cpio –itv 預覽包內文件
rpm2cpio  包文件|cpio –id “*.conf” ”  釋放包內文件
[root@6 cd]# rpm2cpio /misc/cd/Packages/rpm-4.8.0-55.el6.x86_64.rpm |cpio -id /bin/rpm    ##恢復刪除的文件
            
[query-options]
--changelog :查詢rpm包的changelog-c: 查詢程序的配置文件-d: 查詢程序的文檔-i: information-l: 查看指定的程序包安裝后生成的所有文件;--scripts :程序包自帶的腳本片斷-R:查詢指定的程序包所依賴的CAPABILITY; 
--provides:列出指定程序包所提供的CAPABILITY; 
查詢用法:
    -qi PACKAGE, 
    -qf FILE, 
    -qc PACKAGE, 
    -ql PACKAGE, 
    -qd PACKAGE    -qpi PACKAGE_FILE, 
    -qpl PACKAGE_FILE,...    -qa    卸載:
     rpm {-e|--erase} [--allmatches] [--nodeps] [--noscripts] [--notriggers] [--test] PACKAGE_NAME ...


rpm {-V|--verify} [select-options] [verify-options]
    S file Size differs
    M Mode differs (includes permissions and file type)
    5 digest (formerly MD5 sum) differs
    D Device major/minor number mismatch
    L readLink(2) path mismatch
    U User ownership differs
    G Group ownership differs
    T mTime differs
    P capabilities differ

包校驗

包來源合法性驗正及完整性驗正:
    完整性驗正:SHA256
    來源合法性驗正:RSA
公鑰加密:
    對稱加密:加密、解密使用同一密鑰;
    非對稱加密:密鑰是成對兒的    public key:  公鑰,公開所有人
    secret key:  私鑰,  不能公開
導入所需要公鑰:
    rpm -K|checksig rpmfile 檢查包的完整性和簽名
    
     [root@6 cd]# rpm -K /misc/cd/Packages/tree-1.5.3-3.el6.x86_64.rpm 
     /misc/cd/Packages/tree-1.5.3-3.el6.x86_64.rpm: rsa sha1 (md5) pgp md5 OK
     
    rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7        ##導入key文件
    CentOS 7 發行版光盤提供: RPM-GPG-KEY-CentOS-7
    rpm -qa gpg-pubkey*

rpm數據庫

數據庫重建:
   /var/lib/rpmrpm {--initdb|--rebuilddb}    initdb:  初始化
    如果事先不存在數據庫,則新建之
    否則,不執行任何操作
    rebuilddb :重建
    無論當前存在與否,直接重新創建數據庫

yum

CentOS: yum, dnfYUM: Yellowdog Update Modifier,rpm的前端程序,用來解決軟件包相關依賴性,可以在多個庫之間定位軟件包,up2date 的替代工具
yum repository: yum repo ,存儲了眾多rpm 包,以及包的相關的元數據文件(放置于特定目錄repodata 下)
   文件服務器:        ftp://
        http://
        file:///

yum 配置文件

yum 客戶端配置文件:
    /etc/yum.conf :為所有倉庫提供公共配置
    /etc/yum.repos.d/*.repo :為倉庫的指向提供配置
    倉庫指向的定義:
        [repositoryID]
        name=Some name for this repository
        baseurl=url://path/to/repository/
        enabled={1|0}
        gpgcheck={1|0}
        gpgkey=URL
        enablegroups={1|0}
        failovermethod={roundrobin|priority}
        默認為:roundrobin ,意為隨機挑選;
        cost= 默認為1000repo 文件范例
/etc/yum.repo.d/
    [base]
    name=centos 7
    baseurl=http://10.1.0.1/cobbler/ks_mirror/7/
    gpgcheck=1
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentosOS-7
    enabled=1

教學環境yum源

教室里的yum源:http://172.16.0.1/cobbler/ks_mirror/CentOS-X-x86_64/CentOS epel:http://172.16.0.1/fedora-epel/7/x86_64/yum 命令的用法:
yum [options] [command] [package ...]

yum-config-manager

生成172.16.0.1_cobbler_ks_mirror_CentOS-X-x86_64_.repo
yum-config-manager --add-repo=http://172.16.0.1/cobbler/ks_mirror/CentOS-X -x86_64/
yum-config-manager --disable “ 倉庫名" 禁用倉庫yum-config-manager --enable “ 倉庫名”  啟用倉庫

yum

顯示倉庫列表:
    repolist [all|enabled|disabled]顯示程序包:
  list
    # yum list [all | glob_exp1] [glob_exp2] [...]
    # yum list {available|installed|updates} [glob_exp1]
    [...]安裝程序包:
    install package1 [package2] [...]
    reinstall package1 [package2] [...] (重新安裝)


升級程序包:
    update [package1] [package2] [...]
    downgrade package1 [package2] [...] ( 降級)
檢查可用升級:
    check-update
卸載程序包:
    remove | erase package1 [package2] [...]查看程序包information:
   info [...]查看指定的特性( 可以是某文件) 是由哪個程序包所提供:
   provides | whatprovides feature1 [feature2] [...]清理本地緩存:
   clean [ packages | metadata | expire-cache |rpmdb | plugins | all ]構建緩存:
   makecache
搜索:search string1 [string2] [...]
    以指定的關鍵字搜索程序包名及summary 信息
查看指定包所依賴的capabilities:
    deplist package1 [package2] [...]查看yum事務歷史:
    history [info|list|packages-list|packages-info|
    summary|addon-info|redo|undo|
    rollback|new|sync|stats]
    yum history
    yum history info 6
    yum history undo 6
日志:/var/log/yum.log

積累應用

1 、寫 一個服務腳本/root/bin/testsrv.sh ,完成如下要求

(1)  腳本可接受參數:start, stop, restart, status

(2)  如果參數非此四者之一,提示使用格式后報錯退出

(3)  如是start:則創建/var/lock/subsys/ SCRIPT_NAME , 并顯示“啟動成功”考慮:如果事先已經啟動過一次,該如何處理?

(4)  如是stop:則刪除/var/lock/subsys/ SCRIPT_NAME , 并顯示“停止完成”考慮:如果事先已然停止過了,該如何處理?

(5)  如是restart ,則先stop,  再start考慮:如果本來沒有start ,如何處理?

(6)  如是status,  則如果/var/lock/subsys/ SCRIPT_NAME 文件存在,則顯示“ SCRIPT_NAME is running…”如果/var/lock/subsys/ SCRIPT_NAME 文件不存在,則顯示“ SCRIPT_NAMEis stopped…”其中: SCRIPT_NAME 為當前腳 本名

     ###函數
     #! /bin/bash
     servername=SCRIPT_NAME
     START () 
     {  touch  /var/lock/subsys/$servername
         echo  "$servername已啟動."
       }
     STOP()
     {  rm -f   /var/lock/subsys/$servername
          echo  "$servername已停止."
     }
 ###程序
 #! /bin/bash
#author:lvasu
#description:
#version:0.1
#date:
source  agrement
PS3="請選擇參數:"
servername=SCRIPT_NAME
file=/var/lock/subsys/ $servername
select  agre in  start stop restart status;
do
case  $agre in 
start)   
        if  [ -f  $file ];then
           echo "$servername已開啟,不需要啟動."
       else 
               START
       fi
           ;;
stop)     
         if  [ -f  $file ];then
              STOP
       else 
             echo "$servername未開啟,不需要關閉."
       fi
           ;;
status)   
        if  [ -f  $file ];then
             echo "$servername is running...."
       else 
              echo "$servername is stopped..."
       fi
           ;;
restart)          
                      if  [ -f  $file ];then
              echo "$servername已開啟,重啟中."
              STOP    &> /dev/null
              START  
           else 
                echo "$servername 未啟動,啟動中."
                START   
            fi  
           ;;
  *)       
                 echo "你輸入的不合法."
                  break
           ;;
  esac
  done
###執行效果
[root@6 bin]# ./testsrv.sh
1) start
2) stop
3) restart
4) status
請選擇參數:1
SCRIPT_NAME已啟動.
請選擇參數:2
SCRIPT_NAME已停止.
請選擇參數:3
SCRIPT_NAME 未啟動,啟動中.
SCRIPT_NAME已啟動.
請選擇參數:4
SCRIPT_NAME is running....

2 、編寫一個腳本/root/bin/copycmd.sh

(1)  提示用戶輸入一個可執行命令名稱;

(2)  獲取此命令所依賴到的所有庫文件列表

(3)  復制命令至某目標目錄( 例如/mnt/sysroot) 下的對應路徑下;

如:/bin/bash ==> /mnt/sysroot/bin/bash

/usr/bin/passwd ==> /mnt/sysroot/usr/bin/passwd

(4)  復制此命令依賴到的所有庫文件至目標目錄下的對應路徑下:

如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-

linux-x86-64.so.2

(5)每次復制完成一個命令后,不要退出,而是提示用戶鍵入新的要復制的命

令,并重復完成上述功能;直到用戶輸入quit 退出

###程序
#! /bin/bash
#author:lvasu
#description:
#version:0.1
#date:
while true;do
read -p "請輸入一個可執行的命令"  cmd 
addr=/mnt/sysroot
case   $cmd   in  
quit)
        exit
        ;;  
 *)        type $cmd &> /dev/null
           if  [ $? -eq 0 ];then
             which $cmd &> /dev/null 
             if  [ $? -eq 0 ];then
            path=$(which $cmd | sed -rn "/\/.*\/$cmd/p") 
            else  path=/bin/bash
             fi  
             else  echo  "請輸入正確的命令."
              continue
            fi
       echo "復制命令的路徑:"
       echo $path
       echo '=============================='
       files=$(ldd $path| grep -o '/.*.so.[1-9]') 
       echo "$path的庫文件:"
       echo "$files" | tee -a  /testdir/file
       echo '=============================='
       line=$(echo "$files" |wc -l)
       commen1=$(echo $path | sed -nr 's@(^/.*/)[^/]+/?$@\1@p')
       mkdir -p  $addr$commen1 &> /dev/null
       cp  -a $path  $addr$path &> /dev/null
       echo  "$addr$path復制成功."
       echo '=============================='
       while read n;do
          commen2=$(echo $n|sed -nr 's@(^/.*/)[^/]+/?$@\1@p')
           mkdir -p   $addr$commen2 &> /dev/null
          cp -a  $n $addr$commen2   &> /dev/null
           echo "$addr$n復制成功."
        done < /testdir/file 
         rm -f    /testdir/file 
  esac  
done
###執行效果
[root@6 bin]# ./copycmd.sh
請輸入一個可執行的命令cd
復制命令的路徑:
/bin/bash
==============================
/bin/bash的庫文件:
/lib64/libtinfo.so.5
/lib64/libdl.so.2
/lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
==============================
/mnt/sysroot/bin/bash復制成功.
==============================
/mnt/sysroot/lib64/libtinfo.so.5復制成功.
/mnt/sysroot/lib64/libdl.so.2復制成功.
/mnt/sysroot/lib64/libc.so.6復制成功.
/mnt/sysroot/lib64/ld-linux-x86-64.so.2復制成功.
請輸入一個可執行的命令ip
復制命令的路徑:
/sbin/ip
==============================
/sbin/ip的庫文件:
/lib64/libresolv.so.2
/lib64/libdl.so.2
/lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
==============================
/mnt/sysroot/sbin/ip復制成功.
==============================
/mnt/sysroot/lib64/libresolv.so.2復制成功.
/mnt/sysroot/lib64/libdl.so.2復制成功.
/mnt/sysroot/lib64/libc.so.6復制成功.
/mnt/sysroot/lib64/ld-linux-x86-64.so.2復制成功.

3 、斐波那契數列又稱黃金分割數列,因數學家列昂納多·斐波那契以兔子

繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:0 、1 、1 、2 、3 、5 、8 、13 、21 、34 、……,斐波納契數列以如下被以遞歸的

方法定義:F (0 )=0 ,F (1 )=1 ,F (n )=F(n-1)+F(n-2) (n≥2) )

寫一個函數,求n 階斐波那契數列

###函數
tuzi()
{   
       if [ $1 -eq 0 ];then
        echo 0
       elif [ $1 -eq 1 ];then
        echo 1
       else
        echo  $[$(tuzi $[$1-1])+$(tuzi $[$1-2])]
       fi  
}
tuzi2()
{   
     for((i=0;i<=$1;i++))
       if [ $i -eq 0 ];then
        echo 0
       elif [ $i -eq 1 ];then
        echo 1
       else
        echo  $[$(tuzi $[$i-1])+$(tuzi $[$i-2])]
       fi  
    done
}
###程序
#! /bin/bash
#author:lvasu
#description:
#version:0.1
#date:
source  agrement
read -p "請輸入斐波那契數列階數:" n
tuzi $n
echo '==================='
tuzi2 $n
###執行效果
[root@6 bin]# ./feibo.sh
請輸入斐波那契數列階數:10
55
===================
0
1
1
2
3
5
8
13
21
34
55

原創文章,作者:lvasu,如若轉載,請注明出處:http://www.www58058.com/38903

(0)
lvasulvasu
上一篇 2016-08-24 10:25
下一篇 2016-08-24 10:26

相關推薦

  • Linux磁盤和文件系統管理

    磁盤相關概念 設備類型: 塊設備(block):存取單位為塊,典型設備磁盤 字符設備(char):存取單位為字符,典型設備為鍵盤 設備文件: 關聯至一個設備驅動程序,進而能夠跟與之對應硬件設備進行通信。 如果存在兩個相同型號設備,使用兩個設備文件,但可能還會關聯到同一個驅動程序 設備文件只有元數據即屬性,沒有數據內容,屬于特殊文件類型 設備號碼: 主設備號:…

    Linux干貨 2016-06-09
  • 重定向和管道

     重定向    程序:指令+數據    讀入數據:Input    輸出數據:Output  linux給程序提供三種I/O設備    標準輸入(stdin)-0 默認接受來自鍵盤的輸入    標準輸出(stdinout)-1默認輸出到終端…

    Linux干貨 2016-08-10
  • 【26期】Linux第五周學習小總結

        第五周的學習內容很豐富, 從查找到壓縮打包,到軟件包的管理,其中尤其是以壓縮的內容最為豐富,而且龐大的選項讓人絕望,那我今天就總結了一下壓縮的一些東西,和大家一起分享。     為什么會產生壓縮工具呢?因為我們的現在的很多文件會利用到的東西很多,電腦的讀存速度也越來越快,一些大的文件在傳輸和使用上就會很麻煩,雖…

    2017-08-12
  • CentOS 更改改網卡名稱

    1 查看你的CentOS7網卡名字叫什么(通常第一個網卡叫做eno16777736) ip addr 2 編輯配置文件 vi /etc/sysconfig/network-scripts/ifcfg-eno16777736 把配置文件里面所有eno16777736改為eth0 3 把網卡配置文件名字也修改一下 cd?/etc/sysconfig/networ…

    2018-01-18
  • 推薦-虛擬化網絡之OpenvSwitch(二)

    上一篇介紹了openvswitch的基礎知識,接下來我們來做一個實驗,利用GRE通道搭建一個跨多宿主機的虛擬化網絡,深入了解openvswitch的功能。 一、實驗拓撲 ip地址分配:  A1:192.168.10.1/24  A2:192.168.10.10/24   B1:192.168.10.2/24 &nbsp…

    2016-03-27
  • Linux入門之常見文本處理工具

    Linux入門之常見文本處理工具 文本內容查看命令 cat   tac    rev  more  less   head   tail 普通文本查看 cat  tac  rev cat 命令 cat  [option]…

    Linux干貨 2016-08-08
欧美性久久久久