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:
- uma linha de comando
- em um script de shell
- Código C
A saída da tubulação _cmd_ > /dev/stdin
e 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 shell
ou system
externocomandospara 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 TIOCSTI
na fonte do kernel (viaElétrons Livres) mostrará tiocsti
"caractere de entrada falso", que usa um tty_struct
contexto.
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 shell
ser usado para scripts, no entanto, ao contrário de muitos outros aplicativos semelhantes, ele não captura, nem permite, capturar os resultados, apenas permitindo stdin
e stdout
fazendo 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_flip
in src/drivers/tty/tty_buffer.c
, que usa um tty_port
contexto.
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/stdin
ou /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 flip
funçõ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 xvkbd
e xdotool
ou xte
, mas este aplicativo está sendo usado no console Linux (VT).
A resposta (quase) real:
Embora /dev/uinput
não tenha privilégios de usuário (na maioria dos sistemas), sudo
um script que printf
funcionará 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 TIOCSTI
tenha 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-tools
foi absorvido pelo kbd
que writevt
foinã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-tools
pacote. 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 writevt
nã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-tools
pacote?)
ATUALIZAÇÃO: na verdade não consigo mais encontrar console-tools
na busca de pacotes debian (onde verifiquei o conteúdo originalmente), nem mesmo backports.
O projeto do pacote original está aqui:
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 kbd
absorver - 2001
O console-tools
pacote do projeto "Linux Console Tools" ainda está disponível no RPiOS. Não é o mesmo linuxconsoletools
pacote do projeto "Linux Console Project", que também está no SourceForge.