tty에 문자열을 넣어 명령을 구성하십시오.


15

나는 이것을 할 수 있었다

echo -n " command "> / dev / tty1

글자가 나타나고 커서가 움직이지만 글자는 "고스트"입니다. –를 누르면 Enter아무 일도 일어나지 않습니다 (그들은 stdin에 있지 않습니다).

편집하다:

아래 스크린 샷 중간에 내가 왜 이것을 사용하는지 알 수 있습니다. (빨간색 캡션이있는 줄은 노란색 캡션이있는 줄 바로 아래에 있습니다.) 현재와 같이 메모 텍스트를 실제로 "편집"하지는 않습니다. 새 텍스트를 작성하라는 메시지가 표시됩니다.이 텍스트는 편집중인 노트의 텍스트를 대체합니다. 따라서 이전 텍스트를 tty에 붙여 넣으면 해결할 수 있다고 생각했습니다. 사용자가 Enter 키를 누르면 수정이 이루어지지 않습니다. (이 프로그램은 Perl / MySQL에 있지만 "Perl에서이 작업을 수행하는 방법"보다 일반적인 해결책을 찾는 것이 더 흥미로울 것이라고 생각했습니다.)

예

편집 2 :

새로운 C 스크린 샷뿐만 아니라 아래의 C 코드를 사용하는 Perl 코드는 다음과 같습니다. 메모 텍스트-이번에는 오래된 텍스트가 있습니다. 예를 들어 오타를 수정하려는 경우 전체 메모 텍스트를 다시 입력하지 않아도됩니다.

my $edit_note_text = $edit_note_data[2];
print BOLD, RED, " new text: ", RESET;
system("writevt /dev/tty \"$edit_note_text\"");
my $new_text = <$in>;
$new_text = fix_input($new_text);
my $set_text = "UPDATE notes SET note = \"$new_text\" WHERE id = $edit_note_id";
$db->do($set_text);

better_example


관심이 있으시면 Python에서 Stack Overflow를 통해이 작업을 수행했습니다. stackoverflow.com/a/29616465/117471
Bruno Bronosky

문제 진술이 명확하지 않습니다. 무엇이 문제입니까?

답변:


3

방금 writevt트릭을 수행 하는 작은 C 프로그램을 찾았습니다 . 소스 코드를 여기에서 찾으 십시오 . 컴파일하려면 gcc다음 줄을 먼저 제거하십시오.

#include <lct/cline.h>
#include <lct/utils.h>

업데이트 . 이 명령은 현재의 일부 콘솔 도구 배포 사용하지 않는 한, 최근 시스템에 따라서 사용할 수, 인 kbd 대신 콘솔 도구 당신이에서 컴파일 할 수있는 경우, 소스 (훨씬 더 최신 버전, 필요 없음 수정).

용법:

sudo writevt /dev/ttyN command 

어떤 이유로, 당신은 사용이, 그 주 '\r'(또는 '\x0D'대신) '\n'(또는 '\x0A'반환을 보내).


이것은 효과가 있지만 포함하는 것보다 더 잘못된 방법이 있습니다. 사용법 함수를 버리고 a progname_을 작성하고 몇 가지 함수 호출을 주석 처리해야했습니다.main()
Michael Mrozek

@MichaelMrozek이 _()함수는 일반적 으로 사용되는 gettext 의 표시입니다 . 그런 간단한 데모 코드 조각에 약간의 잔인 함이 있지만 내가 아프지 않습니다.
jw013

위 답변 의 링크 가 끊어졌습니다. 나는 또 다른 발견 writevt.c (github.com/에서 여기  grawity ) ; 본질적으로 동일한 프로그램 인 것 같습니다.
G-Man, 'Reinstate

나를 위해 작동하지 않습니다-인쇄 명령 만. 어떤 reasson에 대한 resperctively \ R 또는 \ n prinst RN을 Dending /
Antoniossss

10

터미널은 입력 장치 (예 : 키보드)와 디스플레이 장치 (예 : 모니터)의 두 가지입니다. 터미널에서 읽을 때 입력 장치에서 오는 것을 얻습니다. 터미널에 쓰면 데이터가 디스플레이 장치로갑니다.

터미널에 입력을 강제하는 일반적인 방법은 없습니다. 그렇게 할 필요는 거의 없습니다. 터미널이 필요한 프로그램과 상호 작용해야하는 경우 Expect 또는 Empty 와 같은 전용 터미널 에뮬레이터 또는 Screen 또는 Tmux 와 같은 프로그래밍 가능 터미널 래퍼를 사용하십시오 . ioctl 을 사용하여 Linux 콘솔에 입력을 강제 할 수 있습니다 . xdotool 또는 xmacro 와 같은 도구를 사용하여 X11 터미널 에뮬레이터에 입력을 강제 할 수 있습니다 .


내 게시물을 수정했습니다. 한번 봐봐 내 생각을 보게 될거야
Emanuel Berg

@EmanuelBerg 편집 내용을 이해하기 어렵습니다. 대화식으로 사용중인 프로그램에 입력을 프로그래밍 방식으로 피드하려고합니까? 만약 당신이 원하는 경우에 프로그램을 실행 screen하거나 tmux자신의 사용 stuff(화면) 또는 send-key(TMUX) 명령 또는 붙여 넣기 버퍼 기능을.
Gilles 'SO- 악마 그만'

Perl 코드를 포함하여 두 번째 편집을 수행했습니다. C 바이너리의 호출이 있습니다. 모르겠습니다 ... 너무 간단했기 때문에 (단 한 줄의 코드)-( screen또는 tmux도구를 사용하여 ) 실제로하는 것이 더 낫 습니까?
Emanuel Berg

@EmanuelBerg 그래서 그렇습니다 screen -X stuff 'note version one'.
Gilles 'SO- 악마 중지'

7

최소한 Linux 및 BSD에는 TIOCSTI ioctl이있어 문자를 터미널 입력 버퍼로 되돌릴 수 있습니다 (Linux의 경우 최대 [4096 자]).

#include <sys/ioctl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>

void stackchar(char c)
{
  if (ioctl(0, TIOCSTI, &c) < 0) {
    perror("ioctl");
    exit(1);
  }
}
int main(int argc, char *argv[])
{
  int i, j;
  char c;

  for (i = 1; i < argc; i++) {
    if (i > 1) stackchar(' ');
    for (j=0; (c = argv[i][j]); j++) {
      stackchar(c);
    }
  }
  exit(0);
}

컴파일하고 다음과 같이 호출하십시오.

cmd foo bar < "$some_tty"

일부 tty에서 캐릭터를 다시 푸시합니다.

그리고 펄에서 :

require "sys/ioctl.ph";
ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV;

편집 : 이제는 writevt 솔루션 과 동일한 ioctl이라는 것을 알고 있습니다. TIOCSTI가 VT뿐만 아니라 모든 터미널에서 작동하므로 명령의 주석과 이름이 잘못되었습니다.


질문에 대한 두 번째 수정 사항을 확인하십시오. 나는 @htor에서 얻은 코드를 이미 컴파일했습니다. 볼 수있는 것은 훌륭합니다. 대신이 코드를 사용하면 어떤 이점이 있습니까? (그러나 두 경우 모두
Emanuel Berg

예. 최근 편집 내용을 참조하십시오. 요점은 TIOCSTI ioctl을 사용하는 것입니다. 내가 준 코드는 파일 설명자 0 (stdin)에서 그 코드를 수행합니다.
Stéphane Chazelas

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.