2017-04-09 11 views
-1

저는 Linux 환경에서 몇 가지 바이너리로 작업 중이며 사용자 입력을 스크립팅하려고합니다. 예를 들어, 첫 번째 프로그램 prog1.c로 :read() syscall을 사용하여 프로그램에 사용자 입력을 스크립팅하는 방법은 무엇입니까?

void get_input() { 

    int i; 
    char buffer[32]; 

    i = 0; 

    while (i < 3) { 
     memset(buffer, 0, 32); 
     printf("Enter input: "); 
     fgets(buffer, 31, stdin); 
     printf("Your input: %s\n", buffer); 
     i++; 
    } 
} 

나는 실행 PROG1과 하나가 콘솔에서 직접 입력을 입력 할 수 있습니다, 아니면 스크립트를 프로그램에 입력 및 파이프를 할 수 있습니다.

콘솔에서 직접 입력을 입력 :

# ./prog1 
Enter input: Stuff1 
Your input: Stuff1 

Enter input: Stuff2 
Your input: Stuff2 

Enter input: Stuff3 
Your input: Stuff3 

# 

스크립팅 입력 :

출력의 형식 엉망 조금
# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog1 
Enter input: Your input: Stuff1 

Enter input: Your input: Stuff2 

Enter input: Your input: Stuff3 

# 

이지만, 프로그램이 여전히 예상되는 출력을 표시한다. 내가 콘솔에서 직접 내 입력을 입력 할 수 있습니다

void get_input() { 

    int i; 
    char buffer[32]; 

    i = 0; 
    while (i < 3) { 
     memset(buffer, 0, 32); 
     printf("Enter input: "); 
     read(0, buffer, 31); 
     printf("Your input: %s\n", buffer); 
     i++; 
    } 
} 

가 :

# ./prog2 
Stuff1 
Enter input: Your input: Stuff1 

Stuff2 
Enter input: Your input: Stuff2 

Stuff3 
Enter input: Your input: Stuff3 

# 

이뿐만 아니라 프롬프트 입력을 입력 않습니다 표시되지

내 문제는 두 번째 바이너리 prog2.c 함께 입력을 입력 할 때까지, 그러나 심지어 내 입력을 스크립트 할 수 없다 :

# perl -e 'print "Stuff1\n" . "Stuff2\n" . "Stuff3\n"' | ./prog2 
Enter input: Your input: Stuff1 
Stuff2 
Stuff3 

Enter input: Your input: 
Enter input: Your input: 
# 

나는 d fgets()read() 사이 ifferences 발견 : read()은 시스템 콜 반면

  1. fgets()은 C 함수이다.
  2. fgets()은 개행 문자 또는 EOF가 발생할 때까지 입력을 읽지 만 개행 문자는 read() 시스템 콜에서 동일한 영향을 미치지 않습니다.
  3. read()fgets()에없는 일종의 버퍼링 메커니즘을 사용합니다.

나는 포인트 2와 3이 당면 문제와 가장 관련이 있다고 생각하지만, 내 문제를 해결하는 방법을 알지 못한다.

사용자 입력에는 인쇄 할 수없는 16 진수 바이트가 포함되어 있어야하는데, 이는 콘솔에서 직접 입력하는 것이 불충분하기 때문입니다. 또한 바이너리에 대한 소스 코드를 수정할 수 없으므로 fgets()을 사용하여 입력을 수집하는 해결 방법은 없습니다.

제 질문은 prog2에 입력을 공급하여 prog1과 동일한 동작을 얻는 방법이 있는지 제 질문입니다.

감사합니다.

+0

디버깅 도움말 ("이 코드가 작동하지 않는 이유는 무엇입니까?")에는 원하는 동작, 특정 문제 또는 오류 및 질문 자체에서이를 재현하는 데 필요한 가장 짧은 코드가 포함되어야합니다. 분명한 문제 설명이없는 질문은 다른 독자에게 유용하지 않습니다. See : 최소한의 완전하고 검증 가능한 예제를 만드는 방법. – Olaf

+0

함수 :'fgets()'는 입력 끝 부분에 NUL ('\ 0') 바이트를 배치하는 함수에 여전히 '예비'바이트가있을 때 바이트 입력을 중지 할만큼 똑똑합니다. 따라서 버퍼 길이 매개 변수는 버퍼의 실제 길이가되어야합니다. – user3629249

+0

질문이 완전히 변경되었습니다. –

답변

0
를 사용 ') (FREAD를' ') (읽기'를 사용 (등 NUL 바이트를 포함 할 수 있습니다) 또는

이 문제의 해결 방법을 찾았습니다. 콘솔에서 입력 내용을 스크립팅하기 위해 원하는 방식으로 바이너리와 상호 작용할 수는 없지만 프로그래밍 방식으로이를 수행 할 수있는 방법을 찾았습니다.

나는 subprocess 모듈 래퍼 역할을하는 파이썬 라이브러리 제품군을 사용하고 있지만, 간단하게 쓸 수있는 자신 만의 :이 프로세스로 바이너리를 열 것, 그리고 당신이 할 수있는

p = subprocess.Popen(prog2, stdout=subprocess.PIPE, stdin=subprocess.PIPE) 

파이썬 스크립트 내에서 보내기 및 받기 기능을 사용하여 상호 작용합니다.

나는 이것이 비슷한 문제를 겪은 다른 이들에게 도움이되기를 바랍니다.

3

read(2) 버퍼가 아니라 fgets/printf/etc부터 <stdio.h>까지 수행하면 성능이 향상됩니다.

줄을 읽으려면 fgets을 붙이십시오. 그러나 인쇄 할 수없는 데이터 블록 (예 : 2 진수)을 읽으려면 fread을 사용하십시오. 그리고 어쨌든 반환 값을 확인하십시오.는 '진'파일을 읽을 때

+0

디버깅 할 때 gdb에서 입력을 스크립팅 할 때 다음을 발견했습니다. 이것은 읽기 후 레지스터의 상태()를 호출 할 수 있습니다 : EAX : 0x15 ECX : I 출력에서하지만 '아무튼 추측했습니다 수 0xbffff60c ("Stuff1 \ nStuff2 \ nStuff3 \ n을") 해결 방법을 찾도록 도와주세요. –

1

텍스트 파일을 읽는 '는 fgets()'

+0

본인은 동의하지만 원본 질문에 명시된 바와 같이 소스를 수정할 수있는 옵션이 없으므로 가지고있는 것부터 사용해야합니다. –