日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go标准库os/exec使用指南

發(fā)布時間:2024/4/11 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go标准库os/exec使用指南 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

點擊上方“朱小廝的博客”,選擇“設為星標

回復”1024“獲取獨家整理的學習資料

歡迎跳轉到本文的原文鏈接:https://honeypps.com/golang/go-standard-lib-os-exec-guide/

?

有時我們在寫程序的時候會需要調用系統(tǒng)的某個命令來完成一些任務。Go語言os/exec標準庫就提供這種調用外部命令的功能。

如下面的代碼調用ls命令來查看指定目錄下面的文件:

import?("os""os/exec" )func?ls(path?string)?error?{cmd?:=?exec.Command("ls",?path)cmd.Stdout?=?os.Stdoutreturn?cmd.Run() }func?main()?{if?err?:=?ls("/");?err?!=?nil?{panic(err)} }

再舉一個例子,將小寫轉成大寫:

import?("bytes""fmt""log""os/exec""strings" )func?main()?{cmd?:=?exec.Command("tr",?"a-z",?"A-Z")cmd.Stdin?=?strings.NewReader("some?input")var?out?bytes.Buffercmd.Stdout?=?&outif?err?:=?cmd.Run();?err?!=?nil?{log.Fatal(err)}fmt.Printf("in?all?caps:?%q\n",?out.String()) }

概述

golang下的os/exec包執(zhí)行外部命令,它將os.StartProcess進行包裝使得它更容易映射到stdin/stdout、管道I/O。

與C語言或者其他語言中的“系統(tǒng)”庫調用不同,os/exec包并不調用系統(tǒng)shell,也不展開任何glob模式,也不處理通常由shell完成的其他擴展、管道或重定向。這個包的行為更像C語言的“exec”函數(shù)家族。要展開glob模式,可以直接調用shell,注意避免任何危險的輸入,或者使用path/filepath包的glob函數(shù)。如果要展開環(huán)境變量,請使用package os的ExpandEnv。

所謂的 glob 模式是指 shell 所使用的簡化了的正則表達式。星號(*)匹配零個或多個任意字符;[abc]匹配任何一個列在方括號中的字符(這個例子要么匹配一個 a,要么匹配一個 b,要么匹配一個 c);問號(?)只匹配一個任意字符;如果在方括號中使用短劃線分隔兩個字符,表示所有在這兩個字符范圍內(nèi)的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的數(shù)字)。

注意,這個包中的示例假設是Unix系統(tǒng)。它們不能在Windows上運行,也不能在golang.org和godoc.org使用的Go Playground上運行。

相關函數(shù)定義如下:

Variablesfunc?LookPath(file?string)?(string,?error) type?Cmd//方法返回一個*Cmd,?用于執(zhí)行name指定的程序(攜帶arg參數(shù))func?Command(name?string,?arg?...string)?*Cmd?//func?CommandContext(ctx?context.Context,?name?string,?arg?...string)?*Cmd//執(zhí)行Cmd中包含的命令,并返回標準輸出與標準錯誤合并后的切片func?(c?*Cmd)?CombinedOutput()?([]byte,?error)//執(zhí)行Cmd中包含的命令,并返回標準輸出的切片func?(c?*Cmd)?Output()?([]byte,?error)//執(zhí)行Cmd中包含的命令,阻塞直到命令執(zhí)行完成func?(c?*Cmd)?Run()?error//執(zhí)行Cmd中包含的命令,該方法立即返回,并不等待命令執(zhí)行完成func?(c?*Cmd)?Start()?error//返回一個管道,該管道會在Cmd中的命令被啟動后連接到其標準輸入func?(c?*Cmd)?StderrPipe()?(io.ReadCloser,?error)//返回一個管道,該管道會在Cmd中的命令被啟動后連接到其標準輸出func?(c?*Cmd)?StdinPipe()?(io.WriteCloser,?error)//返回一個管道,該管道會在Cmd中的命令被啟動后連接到其標準錯誤func?(c?*Cmd)?StdoutPipe()?(io.ReadCloser,?error)//func?(c?*Cmd)?String()?string//該方法會阻塞直到Cmd中的命令執(zhí)行完成,但該命令必須是被Start方法開始執(zhí)行的func?(c?*Cmd)?Wait()?error type?Errorfunc?(e?*Error)?Error()?stringfunc?(e?*Error)?Unwrap()?error type?ExitErrorfunc?(e?*ExitError)?Error()?string

各個函數(shù)詳解

func LookPath

函數(shù)定義:

func?LookPath(file?string)?(string,?error)

在環(huán)境變量PATH指定的目錄中搜索可執(zhí)行文件,如過file中有文件分隔符(斜杠),則只在當前目錄搜索。即:默認在系統(tǒng)的環(huán)境變量里查找給定的可執(zhí)行命令文件,如果查找到返回路徑,否則報錯??是PATH$。可提供相對路徑下進行查找,并返回相對路徑。

示例:

import?("fmt""os/exec" )func?main()?{f,?err?:=?exec.LookPath("ls")if?err?!=?nil?{fmt.Println(err)}fmt.Println(f)?//輸出?/bin/ls }

struct Cmd

Cmd代表一個正在準備或者在執(zhí)行中的外部命令。

type?Cmd?struct?{// Path是將要執(zhí)行的命令的路徑。//?該字段不能為空,如為相對路徑會相對于Dir字段。Path?string// Args保管命令的參數(shù),包括命令名作為第一個參數(shù);如果為空切片或者nil,相當于無參數(shù)命令。//?典型用法下,Path和Args都應被Command函數(shù)設定。Args?[]string// Env指定進程的環(huán)境,如為nil,則是在當前進程的環(huán)境下執(zhí)行。Env?[]string// Dir指定命令的工作目錄。如為空字符串,會在調用者的進程當前目錄下執(zhí)行。Dir?string//?Stdin指定進程的標準輸入,如為nil,進程會從空設備讀取(os.DevNull)Stdin?io.Reader// Stdout和Stderr指定進程的標準輸出和標準錯誤輸出。//?如果任一個為nil,Run方法會將對應的文件描述符關聯(lián)到空設備(os.DevNull)//?如果兩個字段相同,同一時間最多有一個線程可以寫入。Stdout?io.WriterStderr?io.Writer// ExtraFiles指定額外被新進程繼承的已打開文件流,不包括標準輸入、標準輸出、標準錯誤輸出。//?如果本字段非nil,entry i會變成文件描述符3+i。////?BUG:?在OS X 10.6系統(tǒng)中,子進程可能會繼承不期望的文件描述符。//?http://golang.org/issue/2603ExtraFiles?[]*os.File// SysProcAttr保管可選的、各操作系統(tǒng)特定的sys執(zhí)行屬性。// Run方法會將它作為os.ProcAttr的Sys字段傳遞給os.StartProcess函數(shù)。SysProcAttr?*syscall.SysProcAttr// Process是底層的,只執(zhí)行一次的進程。Process?*os.Process// ProcessState包含一個已經(jīng)存在的進程的信息,只有在調用Wait或Run后才可用。ProcessState?*os.ProcessState//?下面是隱藏或非導出字段ctx?????????????context.Context?//?nil?means?nonelookPathErr?????error???????????//?LookPath?error,?if?any.finished????????bool????????????//?when?Wait?was?calledchildFiles??????[]*os.FilecloseAfterStart?[]io.ClosercloseAfterWait??[]io.Closergoroutine???????[]func()?errorerrch???????????chan?error?//?one?send?per?goroutinewaitDone????????chan?struct{} }

注:exec在執(zhí)行調用系統(tǒng)命令時,會先對需要執(zhí)行的操作進行一次封裝,然后在執(zhí)行。封裝后的命令對象具有以上struct屬性。而封裝方式即使用下邊的Command函數(shù)。

func Command

函數(shù)定義:

func?Command(name?string,?arg?...string)?*Cmd

函數(shù)返回一個*Cmd,用于使用給出的參數(shù)執(zhí)行name指定的程序。返回值只設定了Path和Args兩個參數(shù)。

如果name不含路徑分隔符(如果不是相對路徑),將使用LookPath獲取完整路徑(就是用默認的全局變量路徑);否則直接使用name。參數(shù)arg不應包含命令名。

示例:

func?main()?{cmd?:=?exec.Command("go",?"version")fmt.Println(cmd.Path,?cmd.Args)//輸出:?/usr/local/go/bin/go [go version] }

注:在調用命令執(zhí)行封裝時,如果不提供相對路徑,系統(tǒng)會使用LookPath獲取完整路徑;即這里可以給一個相對路徑。

以上操作只會將命令進行封裝,相當于告訴系統(tǒng)將進行哪些操作,但是執(zhí)行時無法獲取相關信息。

func Run

函數(shù)定義:

func?(c?*Cmd)?Run()?error

Run執(zhí)行c包含的命令,并阻塞直到完成。

如果命令成功執(zhí)行,stdin、stdout、stderr的轉交沒有問題,并且返回狀態(tài)碼為0,方法的返回值為nil(執(zhí)行Run函數(shù)的返回狀態(tài),正確執(zhí)行Run函數(shù),并不代表正確執(zhí)行了命令);如果函數(shù)沒有執(zhí)行或者執(zhí)行失敗,會返回*ExitError類型的錯誤;否則返回的error可能是表示I/O問題。

即:該命令只會執(zhí)行且阻塞到執(zhí)行結束,如果執(zhí)行函數(shù)有錯則返回報錯信息,沒錯則返回nil,并不會返回執(zhí)行結果。

func Start

函數(shù)定義:

func?(c?*Cmd)?Start()?error

Start開始執(zhí)行c包含的命令,但并不會等待該命令完成即返回。

func Wait

函數(shù)定義:

func?(c?*Cmd)?Wait()?error

Wait會阻塞直到該命令執(zhí)行完成,該命令必須是被Start方法開始執(zhí)行的。

如果命令成功執(zhí)行,stdin、stdout、stderr的轉交沒有問題,并且返回狀態(tài)碼為0,方法的返回值為nil;如果命令沒有執(zhí)行或者執(zhí)行失敗,會返回*ExitError類型的錯誤;否則返回的error,可能是表示I/O問題。Wait方法會在命令返回后釋放相關的資源。

Start和Run的區(qū)別

示例:

func?main()?{cmd?:=?exec.Command("sleep",?"5")//?如果用Run,?執(zhí)行到該步會阻塞等待5s//err?:=?cmd.Run()err?:=?cmd.Start()if?err?!=?nil?{fmt.Println(err)}fmt.Printf("Waiting?for?command?to?finish...")//?Start,?上面的內(nèi)容會先輸出,然后這里會阻塞等待5serr?=?cmd.Wait()fmt.Printf("Command?finished?with?error:?%v",?err) }

注:一個命令只能使用Start()或者Run()中的一個啟動命令,不能兩個同時使用。

func CombinedOutput

函數(shù)定義:

func?(c?*Cmd)?CombinedOutput()?([]byte,?error)

執(zhí)行Cmd中包含的命令,并返回標準輸出與標準錯誤合并后的切片。

示例:

func?main()?{cmd?:=?exec.Command("ls",?"-a",?"-l")out,?err?:=?cmd.CombinedOutput()if?err?!=?nil?{fmt.Println(err)}fmt.Println(string(out)) }

func Output

函數(shù)定義:

func?(c?*Cmd)?Output()?([]byte,?error)

執(zhí)行Cmd中包含的命令,并返回標準輸出的切片。

示例:

import?("fmt""os/exec" )func?main()?{cmd?:=?exec.Command("ls",?"-a",?"-l")out,?err?:=?cmd.Output()if?err?!=?nil?{fmt.Println(err)}fmt.Println(string(out)) }

注:Output()和CombinedOutput()不能夠同時使用,因為command的標準輸出只能有一個,同時使用的話便會定義了兩個,便會報錯。

我們還可以通過指定一個對象連接到對應的管道進行傳輸參數(shù)(stdinpipe),獲取輸出(stdoutpipe),獲取錯誤(stderrpipe)

func StdinPipe

函數(shù)定義:

func?(c?*Cmd)?StdinPipe()?(io.WriteCloser,?error) 

err 返回的是執(zhí)行函數(shù)時的錯誤。StdinPipe方法返回一個在命令Start后與命令標準輸入關聯(lián)的管道。當命令退出時,Wait方法將關閉這個管道。必要時調用者可以調用Close方法來強行關閉管道,例如命令在輸入關閉后才會執(zhí)行返回時需要顯式關閉管道。

示例:

func?main()?{cmd?:=?exec.Command("cat")stdin,?err?:=?cmd.StdinPipe()if?err?!=?nil?{fmt.Println(err)}_,?err?=?stdin.Write([]byte("tmp.txt"))if?err?!=?nil?{fmt.Println(err)}stdin.Close()cmd.Stdout?=?os.Stdoutcmd.Start() }

func StdoutPipe

函數(shù)定義:

func?(c?*Cmd)?StdoutPipe()?(io.ReadCloser,?error)

StdoutPipe方法返回一個在命令Start后與命令標準輸出關聯(lián)的管道。當命令退出時,Wait方法將關閉這個管道。但是在從管道讀取完全部數(shù)據(jù)之前調用Wait是錯誤的;同樣使用StdoutPipe方法時調用Run函數(shù)也是錯誤的。

示例:

func?main()?{//執(zhí)行系統(tǒng)命令,?第一個參數(shù)是命令名稱,?后面參數(shù)可以有多個,命令參數(shù)cmd?:=?exec.Command("ls",?"-a",?"-l")//獲取輸出對象,可以從該對象中讀取輸出結果stdout,?err?:=?cmd.StdoutPipe()if?err?!=?nil?{fmt.Println(err)}//保證關閉輸出流defer?stdout.Close()//運行命令if?err?:=?cmd.Start();?err?!=?nil?{fmt.Println(err)}//讀取輸出結果content,?err?:=?ioutil.ReadAll(stdout)if?err?!=?nil?{fmt.Println(err)}fmt.Println(string(content)) }

輸出重定向到文件:

import?("fmt""os""os/exec" )func?main()?{cmd?:=?exec.Command("ls",?"-a",?"-l")//重定向標準輸出到文件stdout,?err?:=?os.OpenFile("stdout.log",?os.O_CREATE|os.O_WRONLY,?0600)if?err?!=?nil?{fmt.Println(err)}defer?stdout.Close()cmd.Stdout?=?stdout//執(zhí)行命令if?err?:=?cmd.Start();?err?!=?nil?{fmt.Println(err)} }

func StderrPipe

函數(shù)定義:

func?(c?*Cmd)?StderrPipe()?(io.ReadCloser,?error)

StderrPipe方法返回一個在命令Start后與命令標準錯誤輸出關聯(lián)的管道。當命令退出時,Wait方法將關閉這個管道,一般不需要顯式的關閉該管道。但是在從管道讀取完全部數(shù)據(jù)之前調用Wait是錯誤的;同樣使用StderrPipe方法時調用Run函數(shù)也是錯誤的。

示例:

func?main()?{cmd?:=?exec.Command("mv",?"hello")i,?err?:=?cmd.StderrPipe()if?err?!=?nil?{fmt.Printf("Error:%s\n",?err)}b,?_?:=?ioutil.ReadAll(i)if?err?:=?cmd.Wait();?err?!=?nil?{fmt.Printf("Error:?%s\n",?err)}fmt.Println(string(b)) }

應用示例

項目中需要執(zhí)行shell命令,雖然exec包提供了CombinedOutput()方法,在shell運行結束會返回shell執(zhí)行的輸出,但是用戶在發(fā)起一次任務時,可能在不停的刷新log,想達到同步查看log的目的,但是CombinedOutput()方法只能在命令完全執(zhí)行結束才返回整個shell的輸出,所以肯定達不到效果,所以,需要尋找其它方法達到命令一邊執(zhí)行l(wèi)og一邊輸出的目的。

使用重定向

如果你的shell比較簡單,并且log的文件路徑也很容易確定,那么直接對shell執(zhí)行的命令添加重定向最簡單不過了,程序參考如下:

import?("fmt""os/exec" )func?main()?{cmdStr?:=?` #!/bin/bash for?var?in?{1..10} dosleep?1echo?"Hello,?Welcome?${var}?times?" done`cmd?:=?exec.Command("bash",?"-c",?cmdStr+"?>>?file.log")if?err?:=?cmd.Start();?err?!=?nil?{fmt.Println(err)}if?err?:=?cmd.Wait();?err?!=?nil?{fmt.Println(err)} }

上面程序定義了一個每秒1次的shell,但是在shell執(zhí)行前,對shell進行了拼接,使用了重定向,所以我們可以在另外一個終端中實時的看到 log 的變化

指定shell執(zhí)行時的輸出

使用exec.Command創(chuàng)建一個Shell后,就具有了兩個變量:Stdout io.Writer和Stderr io.Writer。

這兩個變量是用來指定程序的標準輸出和標準錯誤輸出的位置,所以我們就利用這兩個變量,直接打開文件,然后將打開的文件指針賦值給這兩個變量即可將程序的輸出直接輸出到文件中,也能達到相同的效果,參考程序如下:

import?("fmt""os""os/exec" )func?main()?{cmdStr?:=?` #!/bin/bash for?var?in?{1..10} dosleep?1echo?"Hello,?Welcome?${var}?times?" done`cmd?:=?exec.Command("bash",?"-c",?cmdStr)file,?_?:=?os.OpenFile("file.log",?os.O_RDWR|os.O_CREATE|os.O_APPEND,?0666)defer?file.Close()//指定輸出位置cmd.Stderr?=?filecmd.Stdout?=?fileif?err?:=?cmd.Start();?err?!=?nil?{fmt.Println(err)}if?err?:=?cmd.Wait();?err?!=?nil?{fmt.Println(err)} }

從shell執(zhí)行結果的管道中獲取輸出

我們可以通過管道獲取命令執(zhí)行過程中的輸出,參考程序如下:

import?("fmt""io""os""os/exec""strings""time" )//通過管道同步獲取日志的函數(shù) func?syncLog(reader?io.ReadCloser)?{file,?_?:=?os.OpenFile("file.log",?os.O_RDWR|os.O_CREATE|os.O_APPEND,?0666)defer?file.Close()buf?:=?make([]byte,?1024,?1024)for?{strNum,?err?:=?reader.Read(buf)if?strNum?>?0?{outputByte?:=?buf[:strNum]file.WriteString(string(outputByte))}if?err?!=?nil?{//讀到結尾if?err?==?io.EOF?||?strings.Contains(err.Error(),?"file?already?closed")?{err?=?nil}?}} }func?main()?{cmdStr?:=?` #!/bin/bash for?var?in?{1..10} dosleep?1echo?"Hello,?Welcome?${var}?times?" done`cmd?:=?exec.Command("bash",?"-c",?cmdStr)//這里得到標準輸出和標準錯誤輸出的兩個管道,此處獲取了錯誤處理cmdStdoutPipe,?_?:=?cmd.StdoutPipe()cmdStderrPipe,?_?:=?cmd.StderrPipe()if?err?:=?cmd.Start();?err?!=?nil?{fmt.Println(err)}go?syncLog(cmdStdoutPipe)go?syncLog(cmdStderrPipe)if?err?:=?cmd.Wait();?err?!=?nil?{fmt.Println(err)}time.Sleep(time.Second?*?5) }

擴展 - 解決log格式亂的問題

上面第三種方式,我們直接是通過打開文件,然后將讀取到的程序輸出寫入文件,但是實際上可能別人又已經(jīng)封裝好了一個logger,讓你往logger里面寫。比如,我這里就使用log包提供的log然后將程序的執(zhí)行結果寫入,但是因為使用了log包,所以寫入的格式和log本身的格式造成格式會有部分的錯亂,參考我的解決辦法,解釋都在注釋里,如下:

import?("fmt""io""log""os""os/exec""strings" )//通過管道同步獲取日志的函數(shù) func?syncLog(logger?*log.Logger,?reader?io.ReadCloser)?{//因為logger的print方法會自動添加一個換行,所以我們需要一個cache暫存不滿一行的logcache?:=?""buf?:=?make([]byte,?1024,?1024)for?{strNum,?err?:=?reader.Read(buf)if?strNum?>?0?{outputByte?:=?buf[:strNum]outputSlice?:=?strings.Split(string(outputByte),?"\n")logText?:=?strings.Join(outputSlice[:len(outputSlice)-1],?"\n")logger.Printf("%s%s",?cache,?logText)cache?=?outputSlice[len(outputSlice)-1]}if?err?!=?nil?{//讀到結尾if?err?==?io.EOF?||?strings.Contains(err.Error(),?"file?already?closed")?{err?=?nil}}} }func?main()?{cmdStr?:=?` #!/bin/bash for?var?in?{1..10} dosleep?1echo?"Hello,?Welcome?${var}?times?" done`cmd?:=?exec.Command("bash",?"-c",?cmdStr)//這里得到標準輸出和標準錯誤輸出的兩個管道,此處獲取了錯誤處理cmdStdoutPipe,?_?:=?cmd.StdoutPipe()cmdStderrPipe,?_?:=?cmd.StderrPipe()if?err?:=?cmd.Start();?err?!=?nil?{fmt.Println(err)}//打開一個文件,用作log封裝輸出file,?_?:=?os.OpenFile("file.log",?os.O_RDWR|os.O_CREATE|os.O_APPEND,?0666)defer?file.Close()//創(chuàng)建封裝的log,第三個參數(shù)設置log輸出的格式logger?:=?log.New(file,?"",?log.LstdFlags)logger.Print("start?print?log:")oldFlags?:=?logger.Flags()//為了保證shell的輸出和標準的log格式不沖突,并且為了整齊,關閉logger自身的格式logger.SetFlags(0)go?syncLog(logger,?cmdStdoutPipe)go?syncLog(logger,?cmdStderrPipe)err?:=?cmd.Wait()//執(zhí)行完后再打開log輸出的格式logger.SetFlags(oldFlags)logger.Print("log?print?done")if?err?!=?nil?{fmt.Println(err)} }

程序執(zhí)行結果如下:

2019/08/11?21:30:51?start?print?log: Hello,?Welcome?1?times? Hello,?Welcome?2?times? Hello,?Welcome?3?times? Hello,?Welcome?4?times? Hello,?Welcome?5?times? Hello,?Welcome?6?times? Hello,?Welcome?7?times? Hello,?Welcome?8?times? Hello,?Welcome?9?times? Hello,?Welcome?10?times? 2019/08/11?21:31:01?log?print?done

參考資料及衍生讀物

  • Go基礎篇5:內(nèi)置模塊

  • golang os/exec 執(zhí)行外部命令

  • https://gowalker.org/os/exec

  • [譯]使用os/exec執(zhí)行命令 GO語言

  • golang os/exec包用法之Kill進程及其子進程

  • ?

    歡迎跳轉到本文的原文鏈接:https://honeypps.com/golang/go-standard-lib-os-exec-guide/

    想知道更多?描下面的二維碼關注我

    精彩推薦:

    • 《遲來的干貨|Kafka權限管理實戰(zhàn)》

    • 《Go命令行Cobra的使用》

    • 《史上最難的10道Java面試題》

    • 《7102-2019年技術文全套整理,建議收藏》

    ?

    ?

    加技術群入口(備注:技術):>>>Learn More<<

    免費資料入口(備注:1024):>>>Learn More<<

    免費星球入口:>>>Free<<<

    ?
    點個"在看"唄^_^

    總結

    以上是生活随笔為你收集整理的Go标准库os/exec使用指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 黄色一级片免费播放 | 欧美一区二区三区大屁股撅起来 | 亚洲va在线∨a天堂va欧美va | 欧美人体做爰大胆视频 | 三女警花合力承欢猎艳都市h | 亚洲自拍偷拍综合 | 亚洲五月婷婷 | 综合久久亚洲 | 国产午夜伦鲁鲁 | 先锋资源一区二区 | 亚洲精久久 | 91香蕉视频污污 | 国产午夜精品在线观看 | 国产精品成人一区二区网站软件 | 蛇女欲潮性三级 | 黄页网站视频在线观看 | 国产一级久久久久毛片精品 | 欧美成人一区二区三区片免费 | 日本乱轮视频 | 久久911| 久久久久夜 | 成人免费毛片足控 | 精品久久久在线观看 | 日本大尺度吃奶做爰久久久绯色 | 综合色伊人 | 欧美激情自拍偷拍 | 不卡的av电影 | 一级性生活毛片 | 91黄色视屏 | 美女少妇一区二区 | 日韩三级中文字幕 | 亚洲天堂美女 | 亚洲精品日韩在线 | 调教撅屁股啪调教打臀缝av | www久久| 黄骗免费网站 | 一起操在线| 爱情岛亚洲论坛入口福利 | www色| 天天碰免费视频 | 亚洲国产精品无码久久久久高潮 | 国产精品1区2区3区 在线看黄的网站 | 欧美在线播放 | 这里只有久久精品 | 国产精品久久国产精品99 | 国产男女精品 | av资源首页| 老鸭窝久久 | 亚洲一区你懂的 | 国产乡下妇女做爰毛片 | 91www| 一区二区三区视频免费视 | 亚洲中字幕 | 国产思思99re99在线观看 | 国产成人精品免费看视频 | 亚洲男人在线天堂 | 亚洲人xxx| 少妇诱惑av | 欧美日韩一区不卡 | 99精品视频免费 | 自拍偷拍激情视频 | 日韩成人在线播放 | 俄罗斯黄色大片 | 女人18岁毛片 | 久精品视频 | 日韩欧av| 一区二区三区www污污污网站 | 亚洲熟女一区二区三区 | 国产免费一区二区三区三州老师 | 国内自拍2020| 素人一区二区三区 | 两个人看的www视频免费完整版 | 色爽爽一区二区三区 | 美女靠逼app | 在线观看av网 | 国产又粗又长又黄视频 | av自拍网| 亚洲一级伦理 | 亚洲天堂中文字幕在线观看 | 中文在线观看免费 | 伊人中文网 | 龚玥菲三级露全乳视频 | 国产精品-区区久久久狼 | 国产91高清| 日日夜夜草 | 黄色国产一区二区 | 亲切的金子餐桌片段的金子 | 日韩高清专区 | 国产精品夜色一区二区三区 | 在线视频欧美日韩 | 五月婷在线视频 | 午夜影院a | 国产伦精品一区二区三区视频黑人 | 久久久18 | 五月天婷婷丁香花 | 成人av不卡| 亚洲AV无码成人精品国产一区 | 欧美日韩亚洲视频 | 色视频免费观看 |