쓰기에 자신의 유닉스에서는 C-에 문제가 경로 및 execv
문제
나는 내 자신의 쉘에서 C.그것은 필요 홈페이지를 원활하게 보시기 위해서는 사용자의 현재 디렉터리,실행하는 명령에 따라 전체 경로(를 사용해야 합 execv고),사용자 디렉토리를 변경을 가진 cd.
이 숙제입니다.선생님만이 우리에게 기본적인 프라이머 C 고 아주 간단한 해골에서 프로그램이 어떻게 작업해야 합니다.이후 나는 쉽게 포기하는 사람이었습을 연구하는 방법에 대해 이렇게 세 개의 일,하지만 지금은 나에 부딪쳤습니다.
이것은 내가 지금까지:
- 표시합니다 사용자의 사용자 이름,컴퓨터,그리고 현재 디렉터리(기본값은 홈 directory).
- 사용자 입력,그리고 도착 입력
- 분할 사용자의 입력으로""배열로 인수
- 분할 환경변수여 경로를":"배열로 토큰
나는 확실하지 않을 진행하는 방법입니다.나는 나가 알을 사용하여 execv 명령하지만 내 연구에서 google 에서 내가지는 않았을 발견 예를 들어 내가 이해합니다.예를 들면,명령은 bin/ls,어떻게 execv 이 전시에서 모든 파일/폴더를 홈 디렉토리?게 하려면 어떻게 합니까 시스템 내가 변경된 디렉토리?
이 사이트를 많이는 데 도움이되었습니다: http://linuxgazette.net/111/ramankutty.html 그러나 다시는 나에 부딪쳤습니다.
당신의 도움을 위한 감사합니다.알려해야하는 경우 게시물의 일부는 기존의 코드,내가 확실하지 않았다면 그것이 필요했지만.
해결책
을 구현하는 cd 명령어 당신은 시스템호출 chdir
.
#include <unistd.h>
int chdir(
const char *path /* the path name */
);
그래서 당신은 전화 할 수 있 다음과 같습니다.
int ret1 = chdir("../foo/bar");
의 반환 값 chdir
0 때 가능한 것이었으로 변경하는 디렉토리 -1 오류가 발생한 경우가 발생했습니다.오류에 대한 통합하는 합의 남자 페이지입니다.
현재 디렉터리를 통해 확인할 수 있는 모든 프로그램,그래서 당신은 실행 ls
없이 모든 인수,다음 ls 검사 디렉터리에서 그것을 실행하고 사용하는 이 디렉토리에서만 인수입니다.이 기능은 ls 지의 execv
전화입니다.
두 번째 부분입니다.
#include <unistd.h>
int execv(
const char *path, /* programm path*/
char *const argv[]/* argument vector*/
);
execv
실행하는 실행 파일에서 주어 path
과 함께 인수를 주어 argv
.그래서 실행하려는 경우 /bin/ls ../foo /bar
, 에,당신은 뭔가가 필요 유사한
char *cmd_str = "/bin/ls";
char *argv[] = {cmd_str, "../foo", "/bar", NULL };
if (execv(cmd_str, argv) == -1 ){
/* an error occurred */
}
오류에 의해 반환 execv
은-1 입니다.당신이 알고 싶다면 왜 그것을 실행하지 못했습니다 comand 을 확인하는 남자 페이지입니다.
이 NULL
에 char *argv[] = {cmd_str, "../foo", "/bar", NULL };
가 있음을 나타내는 다른 인수 후에 NULL
.
세 번째 부분입니다.유닉스 기반 시스템은 일반적으로 치료하는 명령으로 a/에서 그것으로 명령할 수 있는 직접 실행.즉 당신은 처음이 있는지 확인 슬래에 주어진 명령은 문자열입니다.
int ret_value;
if (strchr(cmd_str, '/')
if (execv(cmd_str, argv) == -1 ){
/* an error occurred */
}
없는 경우에는 슬래 다음을 통과해야에 있는 디렉토리 PATH
을 확인하는 경우 다음 명령을 실행할 수 있습니다.그래서 주어진 명령은 ls ../foo /bar
고 가정 할 수 있습의 값 PATH
가 ".:/sbin:/bin:/usr/bin"
.우리는 다음을 시도하는 첫 번째 실행 ./ls ../foo /bar
다음 /usr/bin/ls ../foo /bar
그리고 마지막에 /bin/ls ../foo /bar
.
이게 도움이 되었으면 좋겠습니다.
다른 팁
예를 들어,명령에
bin/ls
, 어떻게execv
이 전시에서 모든 파일/폴더를 홈 디렉토리?게 하려면 어떻게 합니까 시스템 내가 변경된 디렉토리?
모든 프로세스에는 현재 작업 디렉터리를 사용하여 수정할 수 있습 chdir
.자식 프로세스를 상속하는 작업 디렉터리에서 그들의 부모입니다.그래서 일반적으로 귀하의 쉘이 관리하는 그것의 현재 작업 디렉토리에 대응하여 cd
사용자가 입력한 명령.면 명령 입력하지 않은 내장,당신 fork
을 만드는 자식 프로세스한 다음 전화 execv
이 있을 실행합니다.
는 경우에 당신은 개미를 취할 PATH
계정으로한 프로그램이 포함된 이름 없는 디렉토리 부분은,당신은 시도해야 가능한 모든 조합의 PATH
요소와 프로그램으로 이름입니다.할 수 있는지 여부를 확인하라는 파일이 있거나,단순히려 그것을 실행하고 실패하는 경우.모든 경우 execv
호출에 실패했습니다,당신은 전화 _exit
을 종료하기 위해서는 자식 프로세스.
참고 대부분의 껍질이 치료하는 모든 명령을 포함하는 /
경로로는 전달 execv
이 직접 있습니다.경로하지 않습 시작 로 /
, 에,그것은 상대적인 경로를 운영 체제 해결에 대하여 그것을 현재 작업 디렉토리에 있습니다.즉, bin/ls
에서 당신의 예를 참조 ls
바이너리에서 bin
하는 디렉토리의 하위 디렉터리가 현재 작업 디렉토리에 있습니다.만한 명령을 포함하지 않습 /
에서 모든 중 하나로 해석되 내부 명령(아 cd
다)또는 이의 이름을 몇 가지 바이너리에 위치 PATH
.
첫 번째 인수 execv
은 경로를 당신이 계산됩니다.의 첫 번째 요소 argv
전통적으로 목록과 같은 이름으로 enetered,즉지 않고는 추가 PATH
디렉토리에 있습니다.후에는 먼저 인수,추가 명령행 매개변수는 통과하고,다음 NULL
을 종료 목록입니다.
쉘이 ls
의 작업을 수행 할 책임이 있다고 믿는 문제라고 생각합니다.ls
는 쉘의 "부분"이 아닙니다 (이 경우 적어도).은 ls
라는 프로그램을 실행합니다.대부분의 의견은 ls
를 찾는 방법을 설명하는 것으로 보이지만, 나는 그것이 당신이 혼란스러워하는 것이 믿지 않습니다.
쉘의 요점이 쓰기 전에 조심스럽게 고려해야합니다.주석은 "단순히"쉘 "단순히"ls
및 chdir
와 같은 프로그램을 "호출"해야한다는 사실을 간접적으로 지적했습니다.
ls
는 그 자체로 알고 있으며, 인수가 없으면 getcwd
에서 반환 된 현재 작업 디렉토리에있는 파일을 나열해야합니다.