Parece que -C
faz o mpg123 ler a partir do terminal, não do stdin. Eu vejo isso, no entanto, na minha versão da man page do mpg123:
-R, --remote
Activate generic control interface. mpg123 will then read and
execute commands from stdin. Basic usage is ''load <filename> ''
to play some file and the obvious ''pause'', ''command. ''jump
<frame>'' will jump/seek to a given point (MPEG frame number).
Issue ''help'' to get a full list of commands and syntax.
Isso pode ser o que você está procurando; tente mpg123 -vR <pipe
. o
interação em seu exemplo se tornaria algo como o seguinte
(isso define o volume para 30%):
$ cat >pipe
load /some/song.mp3
volume 30
Mas então, o que -C
faz que -R
não resulta na
modo anterior não consegue ler de stdin quando um pipe nomeado, em vez de
um terminal está conectado?
Uma rápida olhada no código-fonte mpg123 indica que ele usa o
instalações da termios para ler as teclas pressionadas do terminal, usando
tcsetattr
para colocá-lo no chamado "modo não canônico", onde
keypresses são transmitidos para o leitor sem processamento adicional
(em particular, sem esperar que uma linha completa tenha sido
digitado):
struct termios tio = *pattern;
(...)
tio.c_lflag &= ~(ICANON|ECHO);
(...)
return tcsetattr(0,TCSANOW,&tio);
(Este é o mesmo que o exemplo de código GNU libc .)
Em seguida, em um loop, uma função get_key
é chamada, que usa select
para dizer se o descritor de arquivo 0 (stdin) tem dados disponíveis e, se
então, lê um byte dele ( read(0,val,1)
). Mas isso ainda não
explique por que um terminal funciona, mas um cano não funciona! A resposta está em
o código de inicialização do terminal:
/* initialze terminal */
void term_init(void)
{
debug("term_init");
term_enable = 0;
if(tcgetattr(0,&old_tio) < 0)
{
fprintf(stderr,"Can't get terminal attributes\n");
return;
}
if(term_setup(&old_tio) < 0)
{
fprintf(stderr,"Can't set terminal attributes\n");
return;
}
term_enable = 1;
}
Observe que, se tcgetattr
ou term_setup
falhar,
term_enable
está definido como 0. (A função para ler as chaves do terminal começa com if(!term_enable) return 0;
.) E, de fato, quando stdin não é um terminal,
tcgetattr
falha, a mensagem de erro correspondente é impressa e a
O código de manipulação de teclas é ignorado:
$ mpg123 -C ~/input.mp3 <pipe
(...)
Can't get terminal attributes
Isso explica por que a tentativa de enviar comandos pelo piping para mpg123
-C
falha. Essa é uma escolha discutível pelos implementadores; presumivelmente
simplesmente permitindo que tcgetattr
/ tcsetattr
falhe (talvez usando
um interruptor para esse propósito), em vez de desabilitar o manuseio de
manipulação de código, sua tentativa teria funcionado.