2015-05-01 205 views
2

的片段下方的目的是傾聽,並從目錄中選擇了幾首歌曲:猛砸描述

exec 3<&1 

find /some/directory -name '*.mp3' -print0 | xargs -0 bash -c ' 
    for i; do 
     mplayer -ss 10 "$i" 1<&3 
     read -p "Select? (y/n)" -n 1 choice 1<&3 
     if [ "$choice" = "y" -o "$choice" = "Y" ]; then 
      echo "$i" > /tmp/selected_songs.txt 
     fi 
    done 
    ' 

exec 3<&- 

的目的是讓mplayer和外殼read從鍵盤接受輸入,但ins't鍛鍊!爲此,我認爲FD 3將指向findxargs進程的鍵盤輸入。這再次被傳遞到執行的外殼,其中mplayer和外殼read被執行;但它沒有!

這裏怎麼回事?

+0

你沒有說的事情到底如何出了問題,但我會猜測「mplayer」無法響應鍵盤命令。如果是這種情況,那麼它並不一定意味着你的重定向失敗 - 這可能意味着'mplayer'使用不同的方法來收集鍵盤輸入,而不是從它的標準輸入讀取,而且'mplayer'啓動時這種方法不起作用來自非交互式shell。特別是,這樣的過程沒有控制終端。 –

回答

1

傻我!這是FD 0 - 不是1 - 應該重定向。這可以作爲一個版本低於預期:

exec 3<&0 
find /media/jeenu/USB/ -type f -print0 | xargs -0 bash -c ' 
    for i; do 
     mplayer -ss 10 "$i" 
     read -p "Select? (y/n/q)" -n 1 choice 
     case "$choice" in 
      [yY]) echo "$i" >> /tmp/selected_songs.txt;; 
      [qQ]) break;; 
     esac 
    done 0<&3 
    ' 
exec 3<&- 
2

首先,我認爲你比這更難。如果你有bash 4,請使用globstar。

shopt -s globstar 
for i in /some/directory/**/*.mp3; do 
    mplayer -ss 10 "$i" 
    read -p "Select? (y/n)" -n 1 choice 
    case "$choice" in 
     [yY]) echo "$i" >> /tmp/selected_songs.txt;; 
    esac 
done 

即使你不這樣做,你可以使用find … -exec bash -c 'yourscript' _ {} +而不是使用xargs做到這一點。

(我也改變了你的>>>因爲我以爲你不想截斷該文件在每遍。)

對於理解這一問題,有各種複雜的東西去錯在這裏,但我會指出一些重要的事情:

  1. 標準輸入是FD 0,但exec 3<&1重複1至3並打開它閱讀
  2. 你似乎試圖改變鍵盤輸入。這很棘手,因爲這樣做與將EOF發送到交互式shell相似。遇到這種情況時,大多數炮彈會關閉。相反,請考慮更改xargs獲取輸入的位置,並保留鍵盤。 (BSD xargs有與之相關的-o選項。請檢查您的聯機幫助頁。)
  3. 您正在對mplayer進行同樣的重定向,並且沒有超時。如果你正在循環閱讀,當你提供輸入時,你如何知道你在循環中的位置?
+0

我同意它應該是更復雜的。但我更關心如何解決文件描述符在這種情況下的工作原理。是的,那應該是'>>'。謝謝。 – Jeenu

+0

是的,只是意識到它必須是0,而不是1! – Jeenu

0

如果你想使用bash子shell,那麼你可以這樣做:

find /media/jeenu/USB/ -type f -print0 | xargs -0 bash <<EOF 
#This is a bash subshell 
#put your code here 
EOF