stdinから読むときにmplayerでコンソール入力を維持する方法は?

stdinから読むときにmplayerでコンソール入力を維持する方法は?

私は遊んでいます。コマンドラインインタフェースmplayer。次のようにスクリプトを作成したいと思います。

find /some/path/ -type f | grep -vif blacklist | mplayer -shuffle -playlist -

blacklistアーティスト名や曲名が書かれたテキストファイルがどこにあるのか、訪問者がいるときや息子が近くにいるときは無視するほうが良いです。 (悪口がたくさん…:D)

mplayerこの文字が表示されると、-コンソール入力は無効になります。マニュアルページから:

-noconsolecontrols
          Prevent MPlayer from reading key events from standard input.  
          Useful when reading data from standard input.  This is automatically  
          enabled when - is found on the command line. [snip]

これにより、ファイル内で個々の曲を検索したりスキップしたりできなくなります。興味深いことに、これはビデオウィンドウでまだ一般的なキーボード入力を可能にするので、ビデオに適用されます。

一般的なコンソール入力をどのように復元できますか?もちろんこれが最も簡単な解決策ですが、一時ファイルを使用するのを避けたいと思います。-slaveそして-inputそれは合わないようで頑張っても-consolecontroles効果がないようです。

答え1

標準入力ではなくファイル記述子に入力を提供します。

find /some/path/ -type f | grep -vif blacklist |
mplayer -shuffle -playlist /dev/fd/3 3<&0 </dev/tty

最後の行の説明:grepのデータは標準入力から得られます。ファイル記述子0. シェルから標準入力以外のものにパイプする方法はありませんが、いくつかの追加のパイピングを実行できます。まず、ファイルディスクリプタ3をファイルディスクリプタ0の場所にリンクします3<&0。次に、ファイル記述子0(つまり標準入力)を端末に接続します</dev/tty。私たちはmplayerにファイルディスクリプタ3からプレイリストを読むように指示します。 mplayerはファイル名を期待しているので、それをに渡してプロセスがファイルを開くと、そのプロセスの/dev/fd/3ファイル記述子3のように動作します。

リダイレクトの順序は重要であり、直観が間違っている場合は直観に反する可能性があります。3<&0 </dev/ttyfd 3はfd 0が以前に読み取った場所から読み取られ、fd 0はから読み取られます/dev/tty</dev/tty 3<&0fd 0とfd 3は同時に読み取られます/dev/tty

答え2

これは少し過剰ですが、まだ実行可能な解決策かもしれません。ヒューズ ファイルシステムフィルタリングをサポートします。FSフィルタリングまたはロープスフィルターFS公開とても便利なようです。欠落しているファイルを非表示にします。user.public 拡張ファイル属性( xattr)

mplayerこれらのいずれかを使用すると、すべてのファイルをミックスして制御を維持できますstdin。 (ただし、2つのプレイリストを作るのに比べるとかなり大変な作業です。)

答え3

ファイル記述子を明示的になりすます代わりに、BashにはパイプをFDに渡す便利な方法があります。

mplayer -shuffle -playlist <(find /some/path -type f -not -name '*.foo')

<(COMMAND)これを行うには、(出力をコマンドにパイプ)と(出力をコマンドにパイプ)の両方を使用できます。>(COMMAND)通常、/dev/fd/ファイル名の代わりに/proc/self/fd/ファイル名を使用して機能しますが、すべての手間をかけずに効果は同じです。

もちろん、mplayerは/proc/self/fdでプレイリストファイルと同じディレクトリにある非絶対プレイリストコンテンツファイルを探します。 (/ dev / fdソリューションにも同じことが当てはまります。)毎日コマンドのstdoutを介して手動で入力し<()たり、他の端でそのデータを選択しないで実行されるコマンドから終了コードをキャプチャすることはできません>()。これは機能しません。コマンドラインの使用には重要ではありませんが、スクリプトに問題がある可能性があります。

答え4

xargs -o次のオプションを使用できます。

find /some/path/ -type f -print0 2>/dev/null | grep -vif blacklist | xargs -0 -o mplayer -shuffle

man xargs:

-o, --open-tty

コマンドを実行する前に、サブプロセスで/ dev / ttyでstdinを再度開きます。これは、xargsに対話型アプリケーションを実行させる場合に便利です。

関連情報