forçar a saída para entrada (buffer) como "\033[6n" em um script

forçar a saída para entrada (buffer) como "\033[6n" em um script

Eu tentei usar pipes e redirecionamentos para que a saída (programa C ou scripts) acabe no buffer de entrada, da mesma forma printf "\033[6n", mas sem resultados positivos.

Alguém sabe como isso é possível como:

  1. uma linha de comando
  2. em um script de shell
  3. Código C

A saída da tubulação _cmd_ > /dev/stdine o código C fprintf(stdin, "blah\n");não têm efeito mensurável.

Observação:Não quero "canalizar" a entrada para outro comando, quero "injetar" caracteres no "buffer do teclado" (por assim dizer).

EDITAR:o caso de uso original era um aplicativo CLI em sandbox que permite shellou systemexternocomandospara interagir com o sistema operacional (por exemplo, Bas), mas nãonãolidar com descritores de arquivo.

Responder1

Editar:A resposta curtaera /dev/uinput, agora é TIOCSTI(veja o final da postagem)


Esta é a resposta até agora e para responder aos comentários:

ioctl_tty(2)Eu não tenho, mas uma pesquisa TIOCSTIna fonte do kernel (viaElétrons Livres) mostrará tiocsti"caractere de entrada falso", que usa um tty_structcontexto.

O aplicativo em questão está em execução o tempo todo, de forma interativa, portanto, pipes e redirecionamentos não podem ser usados. Ele pode shellser usado para scripts, no entanto, ao contrário de muitos outros aplicativos semelhantes, ele não captura, nem permite, capturar os resultados, apenas permitindo stdine stdoutfazendo suas coisas normalmente.

Num futuro próximo, não há chance de mudar isso, não é minha aplicação. No entanto, consegui cortar os resultados de "\033[6n", que foram injetados no buffer do teclado pelo kernel por meio de tty_insert_flip_char& tty_schedule_flipin src/drivers/tty/tty_buffer.c, que usa um tty_portcontexto.

Se não me falha a memória, antes da estrutura do arquivo FD ser alterada, quando haviaapenas4 descritores de arquivo, talvez tenha sido possível conseguir isso. Hoje em dia, embora você possa escrever para /dev/stdinou /proc/self/fd/0, eles estão conectados /dev/tty#e qualquer coisa escrita em um dispositivo TTY acabará na tela ( /dev/stdout). O kernel parece ignorar a rota do descritor de arquivo ao usar TTY, observe que as flipfunções se referem a ele como umporta.

Qualquer aplicativo de usuário não tem acesso a nenhuma dessas funções do kernel. No X-Windows é possível usar xvkbde xdotoolou xte, mas este aplicativo está sendo usado no console Linux (VT).


A resposta (quase) real:

Embora /dev/uinputnão tenha privilégios de usuário (na maioria dos sistemas), sudoum script que printffuncionará com todos os argumentos.

Alternativamente, o tecladoeventotambém funcionará, pois todos os usuários têm acesso a ele, mas muda por inicialização e por sistema (o meu é normalmente /dev/input/event0, mas nem sempre).

Após mais pesquisas, nenhuma dessas abordagens é prática, especialmente para scripts. O que precisamos entender sobre o que precisa ser feito é que queremos apenas apresentartextono buffer de entrada, não "simule um pressionamento de tecla" (que é como funcionam os dispositivos acima).


A resposta real (mais prática):

Uma pergunta externa referia-se a uma resposta no stackexchange, de 2011 (aqui). Ele usa TIOCSTI. Depois de revisar novamente o exemplo Perl, ele também pode ser prático para scripts, onde um aplicativo não é fornecido.

perl -le 'require "sys/ioctl.ph";
      ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV
     ' `_cmds_`

No entanto, ele também ecoa na tela. Depois de muitas horas de pesquisas e experimentações adicionais, o seguinte é prático em um script ou na linha de comando:

stty -echo; perl -le 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV ' `_cmds_` ;stty echo

Observação:embora TIOCSTItenha sido revogado emOpenBSD 6.2(outubro de 2017), aparentemente os desenvolvedores do Kernel Linux são doopostomente, recusando-se categoricamente a revogá-lo (você pode ler mais sobre isso noDiário do OpenBSD).

Responder2

A partir do Debian Bullseye, console-toolsfoi absorvido pelo kbdque writevtfoinãoincluído. Se quiser, as fontes estão vinculadas na atualização no final deste post.


writevt /dev/tty# text, pelo menos no Linux, talvez BSD e Unix, atualmente faz parte do console-toolspacote. O usuário deve terescreverprivilégios para o VT. Especificamente, (EDITAR: se estiver disponível no seu sistema operacional), a resposta completa e correta ao OP é:

writevt `tty` "`_cmds_`"

Esta questão mostra a falta de conhecimento profundo sobre os sistemas operacionais básicos por parte da comunidade StackExchange como um todo. writevté muito antigo, é um comando básico instalado em 99% dos sistemas (EDIT: Debian Linux). Até junho de 2002 não havia nenhuma página de manual ou mantenedor para ele no Debian, o que pode explicar por que muitas pessoas não sabem sobre ele, mesmo que isso tenha acontecido há 15 anos. No entanto, mesmo no Kali Linux (que temtudo) na maioria das vezes não está listado emdisponível comandos, embora esteja lá desde o início.


A partir do Debian Buster writevtnão é mais instalado por padrão e, segundo alguns, pode nem existir mais em nenhum pacote (por falta do Mantenedor? ou mudança no console-toolspacote?)

ATUALIZAÇÃO: na verdade não consigo mais encontrar console-toolsna busca de pacotes debian (onde verifiquei o conteúdo originalmente), nem mesmo backports.

O projeto do pacote original está aqui:

http://lct.sourceforge.net/

Não são necessários patches. Raspbian/RPiOS tem compilação debian (Wheezy to Buster) aqui:

http://raspbian.raspberrypi.org/raspbian/pool/main/c/console-tools/

Citação de Yan Dirson:

Projetos de software (públicos) atuais em que trabalho O projeto Debian GNU/Linux, do qual sou membro desde 1997.

http://ydirson.free.fr/en/software/

esperando para kbdabsorver - 2001

O console-toolspacote do projeto "Linux Console Tools" ainda está disponível no RPiOS. Não é o mesmo linuxconsoletoolspacote do projeto "Linux Console Project", que também está no SourceForge.

informação relacionada