2012-10-14 3 views
0

그래서 저는 C로 기본 UNIX 미니 쉘을 프로그래밍하고 있습니다. 그러나 모든 것이 순조롭게 진행되고 있지만, 최근 콘솔에서 가져온 원래 문자열의 인수를 구문 분석하는 방식을 다시 생각합니다. 인수 배열은 다음과 같습니다 C UNIX 쉘 execvp 따옴표 붙이기

$> echo HELLO "" WORLD! 
HELLO "" WORLD! 

: [! echo0, HELLO0 ","0 WORLD 0]

내가 지금처럼 전달합니다

execvp(args[0], args); 
여기가 구문 분석하는 방식의 예

그러나 echo는 따옴표를 생략하고 사용자가 볼 수있는 것처럼 출력합니다. 필자의 경우 echo는 내장 명령이 아니기 때문에 인쇄 방법을 사용자 정의 할 수는 없습니다. 왜 이런 일이 일어날 지 아무도 몰라? 큰 따옴표를 생략하고 싶지만 다른 모든 종류의 문자를 포함하고 싶습니다 (물론 null도 제외). 그러나 빈 문자열 때문에, 인수 자체로 계산 :

echo HELLO "" WORLD! 

해야 출력 : 아니, 그 사이에

HELLO WORLD! 

2 공간 : 단 하나

HELLO WORLD! 

(AN 이후 빈 문자열은 인수입니다).

너무 혼란스럽지 않기를 바랍니다. 너희들에게 명확한 설명이 필요하면 부탁한다. 나는 코드를 게시하게되어 기쁘다.

답변

2

명령 줄을 구문 분석 할 때 따옴표를 제거하는 셸입니다. exec*에 직접 전화를 걸면 echo가 울립니다. 다음은 echo HELLO '""' WORLD!과 같습니다.

+0

흠, 그래서 따옴표를 직접 제거하여 exec *에 전달해야합니까? – robins35

+0

빈 문자열의 경우는 어떻게됩니까? 어떻게 표현할 수 있습니까? – robins35

+0

@Scriptonaut 예제를 사용하여 :'[echo0, HELLO0, 0, WORLD! 0]'. –

1

/bin/echo 따옴표에 대해 알지 못합니다. 공백으로 구분 된 모든 인수를 단순히 인쇄합니다. 쉘에서 작동하는 이유는 셸이 따옴표를 알고 두 번째 인수로 빈 문자열을 전달하기 때문입니다.

+0

그러면 빈 문자열을 어떻게 나타낼 수 있습니까? 모든 인용문에 대해 null을 삽입 할 수는 없으며 모든 인용문에 대해 memmove를 사용할 수 없습니다. 왜냐하면 내가 가진 arg 중 하나가 전혀 필요하지 않은 경우가 있기 때문입니다. – robins35

+0

@Scriptonaut 따옴표를 구문 분석하는 적절한 작업을 수행해야합니다. 최소한 유한 상태 기계가 필요합니다. – dmckee

1
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main(void) 
{ 
    char *args1[] = { "/bin/echo", "HELLO", "\"\"", "WORLD!", 0 }; 
    char *args2[] = { "/bin/echo", "HELLO", "",  "WORLD!", 0 }; 
    if (fork() == 0) 
    { 
     execvp(args1[0], args1); 
     exit(1); 
    } 
    while (wait(0) > 0) 
     ; 
    execvp(args2[0], args2); 
    return(1); 
} 

이것은 차이점을 보여줍니다. execvp()을 사용할 때 I/O 리디렉션 등을 해석 할 셸이 없습니다. 명령의 경로를 지정 했으므로이 경우에도 execv()도 수행합니다.

+0

그래서 정확히 null 문자를 삽입하지 않고 따옴표를 생략합니까? 예 : echo HELLO ""WORLD! 두 개의 인수 인 echo와 나머지 부분입니다. 각 따옴표에 null 문자를 삽입하면 세 개의 인수로 나타납니다. – robins35

+0

실제로 "할 것"이 아닙니다 - 경로를 지정하면 execvp는 무의미 해지며 어떤 이유로 든 echo는'/ usr/bin/echo'에서만 사용할 수 있습니다. (그것이 어떤 방식 으로든 질문과 관련이있는 것은 아닙니다.) –

+0

자, @Scriptonaut, 그것은 여러분의 코드입니다. 여러분의 의견을 어떻게 해석해야하는지 어떻게 말할 수 있습니까? 쉘을 사용하여 실행하는 것처럼 정확히 작동하게하려면'system'을 사용하십시오. –