Como posso manter a entrada do console no mplayer ao ler stdin?

2

Estou brincando com a interface de linha de comando de mplayer . Eu gostaria de fazer o script da seguinte maneira

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

onde blacklist é um arquivo de texto com nomes de artistas ou músicas que eu prefiro ignorar quando tenho visitantes ou meu filho está por perto (muitos palavrões ...: D)

Quando mplayer encontra o caractere - , desativa a entrada do console. Na página do manual:

-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]

Isso me impede de procurar no arquivo e pular músicas individuais. Engraçado, isso funciona para vídeos, porque a janela de vídeo ainda aceita as entradas habituais do teclado.

Como posso ter a entrada normal do console de volta? Eu gostaria de evitar o uso de um arquivo temporário, embora esta seja, obviamente, a solução mais fácil. -slave e -input não parecem adequados e tentar -consolecontroles não funciona.

    
por Sebastian 30.01.2012 / 11:38

4 respostas

6

Alimente a entrada em um descritor de arquivo diferente da entrada padrão.

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

Explicação da última linha: os dados do grep estão chegando na entrada padrão, que é o descritor de arquivo 0. Não há como canalizar para qualquer lugar além da entrada padrão no shell, mas podemos fazer um pouco de encanamento extra. Primeiro, conectamos o descritor de arquivo 3 a qualquer lugar onde o descritor de arquivo 0 é: 3<&0 . Em seguida, conectamos o descritor de arquivo 0 (ou seja, entrada padrão) ao terminal: </dev/tty . Dizemos ao mplayer para ler a lista de reprodução do descritor de arquivos 3; O mplayer espera um nome de arquivo, então passamos /dev/fd/3 , que quando aberto por um processo se comporta exatamente como o descritor de arquivo 3 naquele processo naquele momento.

Observe que a ordem de redirecionamentos é importante e contraintuitiva se você tiver intuição errada. 3<&0 </dev/tty tem fd 3 leitura de onde fd 0 leu antes e fd 0 leu% de /dev/tty . </dev/tty 3<&0 teria ambos fd 0 e fd 3 lidos de /dev/tty .

    
por 31.01.2012 / 01:17
2

Isso é um pouco exagerado, mas ainda pode ser uma solução viável: use algum FUSE filesystem compatível com filtragem, por exemplo FilterFS ou filtrado por rofs . RevealFS também é útil - está ocultando arquivos que não possuem user.public atributo do arquivo expandido ( xattr ) .

Usando um desses, você provavelmente poderia dizer a mplayer para embaralhar todos os arquivos e, assim, manter os controles stdin . (Comparado com a criação de duas listas de reprodução, isso é um grande esforço, no entanto.)

    
por 30.01.2012 / 16:49
2

Como uma alternativa a explicitamente desdobrar com descritores de arquivos, no Bash você tem uma maneira conveniente de fazer pipelines-as-FDs:

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

Você tem os dois <(COMMAND) (saída do pipe do comando) e >(COMMAND) (saída do canal no comando) para esse tipo de propósito. Eles normalmente trabalham usando / proc / self / fd / nomes de arquivos em vez de / dev / fd / ones, mas o efeito é o mesmo, apenas sem todo o trabalho.

Tenha em mente, é claro, que o mplayer irá procurar por arquivos de conteúdo de lista de reprodução não-absolutos no mesmo diretório que o arquivo de lista de reprodução; neste caso, / proc / self / fd. (O mesmo vale para a solução / dev / fd.) Você também não tem como capturar códigos de saída do comando em execução em <() ou >() , sem alimentá-los manualmente através do stdout do comando e selecionando esses dados no do outro lado - para o uso diário da linha de comando, isso não importa, mas para o script pode ser bastante incômodo.

    
por 09.12.2015 / 02:06
1

Você pode usar a opção xargs -o , por exemplo:

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

man xargs :

-o, --open-tty

Reopen stdin as /dev/tty in the child process before executing the command. This is useful if you want xargs to run an interactive application.

    
por 29.10.2018 / 15:13