2014-11-15 74 views
1

作爲使用shell腳本的初學者,我編寫了這個bash腳本函數來返回文件的md5sum,同時爲用戶提供一個GUI進度條。如何避免在此bash腳本中使用臨時文件?

md5sum_of_file() { 
    (pv -n $1 | md5sum | sed -e 's/\s.*//g' > /tmp/md5sum) 2>&1 | zenity --progress --auto-close 
    echo $(</tmp/md5sum) 
    rm /tmp/md5sum 
} 

pv -n $1饋送文件到md5sum | sed -e 's/\s.*//g'(SED條之和的相關聯的文件名的輸出),而管道中的百分比zenity --progress --auto-close。 (pv -n $ 1 | $(md5sum | sed -e's/\ s。* // g'))「我知道你不能在這個實例中簡單地將校驗和賦值給一個變量,因爲」(pv -n $ 1 | $(md5sum | sed -e's/\ s。* // g'))「在它自己的子shell中。但有沒有辦法做到這一點,而不創建一個臨時文件(在這種情況下「/ tmp/md5sum」)?

謝謝。

+0

爲什麼不是:'pv -n $ 1 | md5sum | sed -e's/\ s。* // g'| zenity --progress --auto-close' – anubhava

+0

你的流水線真的很奇怪......所以你有一個可執行文件,其名稱是通過'pv'輸入的md5總和?你想執行它? –

+0

@gniourf_gniourf - 哎呀抱歉 - 修正了這個問題。我認爲命令替換從我身上遺留下來,試圖將md5sum分配給父shell中的變量(在我瞭解子shell中的變量作用域之前)。剛開始嘗試今天學習Bash:P。 – Inops

回答

2

zenity使用的唯一的事情是標準從pv錯誤,所以使用進程替換來做到這一點,而不涉及其他命令的任何標準輸出或標準錯誤。這使得sed的輸出只需轉到標準輸出,而不需要任何臨時文件 。

pv -n "$1" 2> >(zenity --progress --auto-close) | md5sum | sed -e 's/\s.*//g' 
1

我想這會做(在bash):

md5sum_of_file() { 
    local md5sum 
    read -r md5sum _ < <({ { pv -n "$1" | md5sum >&3; } 2>&1 | zenity --progress --auto-close; } 3>&1) 
    echo "$md5sum" 
} 

我們正在做管道的一點點位置:

  • pv的標準輸出(即的內容文件)通常傳遞到md5sum,並且md5sum的輸出被重定向到文件描述符3;
  • 然後將pv的標準錯誤流重定向到標準輸出以饋送到zenity;
  • 之後,我們將文件描述符3(記住,它的md5sum的輸出)重定向到標準輸出,由read讀取;
  • read只讀取第一個字段(這樣我們就不需要sed來剪切文件名);
  • 終於,我們echo的結果。

如果你的功能不僅是(也就是你只想echo md5值),你也可以做這樣的:

md5sum_of_file() { 
    { { pv -n "$1" | md5sum >&3; } 2>&1 | zenity --progress --auto-close; } 3>&1 | { read -r md5sum _; echo "$md5sum"; } 
} 
相關問題