일반적인 Unix / Linux 프로그램은 명령 행 입력을 인수 개수 ( int argc
) 및 인수 벡터 ( char *argv[]
) 로 받아들 입니다. 의 첫 번째 요소 argv
는 프로그램 이름이며 실제 인수가 뒤에옵니다.
프로그램 이름이 실행 파일에 인수로 전달되는 이유는 무엇입니까? 자신의 이름을 사용하는 프로그램의 예가 exec
있습니까?
답변
우선, argv[0]
반드시 프로그램 이름은 아닙니다. 호출자가 시스템 호출 에 넣는 것 argv[0]
입니다 execve
(예 : Stack Overflow에서이 질문 참조 ). (다른 모든 변형은 exec
시스템 호출이 아니라에 대한 인터페이스 execve
입니다.)
예를 들어, (사용하여 다음, 가정 execl
) :
execl("/var/tmp/mybackdoor", "top", NULL);
/var/tmp/mybackdoor
는 실행되지만 argv[0]
로 설정되어 top
있으며 이는 ps
실제 또는 실제 top
표시됩니다. 이에 대한 자세한 내용 은 U & L SE 에서이 답변 을 참조하십시오 .
옆이 모든 설정 : 같은 공상 파일 시스템의 출현하기 전에 /proc
, argv[0]
프로세스가 자신의 이름에 대해 배울 수있는 유일한 방법이었다. 무엇이 좋을까요?
- 몇몇 프로그램은 호출 된 이름에 따라 동작을 사용자 정의합니다 (보통 BusyBox의 유틸리티 와 같은 기호 또는 하드 링크에 의해 ;이 질문에 대한 다른 답변에서 더 많은 예제가 제공됩니다).
- 또한 syslog를 통해 기록하는 서비스, 데몬 및 기타 프로그램은 종종 이름에 로그 항목을 추가합니다. 이것이 없으면 이벤트 추적이 불가능 해집니다.
답변
많은:
- 배쉬에서 실행 POSIX 모드 때
argv[0]
입니다sh
. 로argv[0]
시작할 때 로그인 쉘로 실행됩니다-
. - 로 실행하면 빔이 다르게 작동
vi
,view
,evim
,eview
,ex
,vimdiff
, 등 - 이미 언급했듯이 Busybox.
- init로 시스템이 설정된 시스템
shutdown
에서reboot
, 등은 심볼릭 링크systemctl
입니다. - 등등.
답변
역사적으로, argv
명령 행의 “단어”에 대한 포인터 배열 일 뿐이므로 프로그램의 이름 인 첫 번째 “단어”로 시작하는 것이 좋습니다.
그리고 어떤 이름을 사용하여 호출하는지에 따라 다르게 동작하는 프로그램이 많이 있으므로 다른 링크를 만들고 다른 “명령”을 얻을 수 있습니다. 내가 생각할 수있는 가장 극단적 인 예는 busybox 인데, 호출 방식에 따라 수십 가지의 “명령”처럼 작동합니다 .
편집 : 요청에 따라 Unix 1st Edition에 대한 참조
하나는에서 예를 볼 수있는 주요 의 기능을 cc
그 argc
와 argv
이미 사용되었다. 쉘 복사 상기 인수 parbuf
내부 newarg
루프의 일부 인수와 동일한 방식으로 명령 자체를 처리하는 동안. (물론, 나중에 명령의 이름 인 첫 번째 인수 만 실행합니다). 그것은 execv
친 해졌고 친척은 존재하지 않았습니다.
답변
사용 사례:
프로그램 이름 을 사용하여 프로그램 동작을 변경할 수 있습니다 .
예를 들어 실제 바이너리에 대한 심볼릭 링크를 만들 수 있습니다.
이 기술을 사용하는 유명한 예로는 하나의 단일 바이너리와 많은 심볼릭 링크를 설치하는 busybox 프로젝트가 있습니다. (ls, cp, mv 등). 대상은 소형 임베디드 장치이기 때문에 저장 공간을 절약하기 위해 수행하고 있습니다.
이것은 setarch
util-linux 에서도 사용됩니다 :
$ ls -l /usr/bin/ | grep setarch
lrwxrwxrwx 1 root root 7 2015-11-05 02:15 i386 -> setarch
lrwxrwxrwx 1 root root 7 2015-11-05 02:15 linux32 -> setarch
lrwxrwxrwx 1 root root 7 2015-11-05 02:15 linux64 -> setarch
-rwxr-xr-x 1 root root 14680 2015-10-22 16:54 setarch
lrwxrwxrwx 1 root root 7 2015-11-05 02:15 x86_64 -> setarch
여기서 그들은 기본적 으로이 기술을 사용하여 많은 중복 소스 파일을 피 하거나 소스를 더 읽기 쉽게 유지합니다.
다른 사용 사례는 런타임에 일부 모듈이나 데이터를로드해야하는 프로그램입니다. 프로그램 경로가 있으면 프로그램 위치에 상대적인 경로에서 모듈을로드 할 수 있습니다 .
또한 많은 프로그램 이 프로그램 이름을 포함한 오류 메시지를 인쇄합니다 .
왜 :
- POSIX 규칙 (
man 3p execve
) 이기 때문에 :
argv는 새 프로그램에 전달 된 인수 문자열의 배열입니다. 일반적으로 이러한 문자열 중 첫 번째 문자열은 실행중인 파일과 관련된 파일 이름을 포함해야합니다.
- C 표준 (적어도 C99 및 C11)입니다.
argc의 값이 0보다 큰 경우 argv [0]이 가리키는 문자열은 프로그램 이름을 나타냅니다. 프로그램 이름을 호스트 환경에서 사용할 수없는 경우 argv [0] [0]은 널 문자입니다.
C 표준은 “파일 이름”이 아니라 “프로그램 이름”이라고 표시합니다.
답변
호출 방식에 따라 동작을 변경하는 프로그램 외에도 프로그램 argv[0]
사용법을 인쇄하는 데 유용합니다.
printf("Usage: %s [arguments]\n", argv[0]);
이로 인해 사용법 메시지가 항상 호출 된 이름을 사용합니다. 프로그램 이름이 바뀌면 사용법 메시지가 변경됩니다. 호출 된 경로 이름도 포함합니다.
# cat foo.c
#include <stdio.h>
int main(int argc, char **argv) { printf("Usage: %s [arguments]\n", argv[0]); }
# gcc -Wall -o foo foo.c
# mv foo /usr/bin
# cd /usr/bin
# ln -s foo bar
# foo
Usage: foo [arguments]
# bar
Usage: bar [arguments]
# ./foo
Usage: ./foo [arguments]
# /usr/bin/foo
Usage: /usr/bin/foo [arguments]
특히 사방에 살 수있는 작은 특수 목적 도구 / 스크립트에 특히 좋습니다.
이것은 GNU 도구에서도 일반적인 관행으로 보입니다 ls
. 예를 들어 다음을 참조하십시오 .
% ls --qq
ls: unrecognized option '--qq'
Try 'ls --help' for more information.
% /bin/ls --qq
/bin/ls: unrecognized option '--qq'
Try '/bin/ls --help' for more information.
답변
프로그램 타이핑을 실행합니다 :
program_name0 arg1 arg2 arg3 ...
.
따라서 쉘은 이미 토큰을 나눠야하며 첫 번째 토큰은 이미 프로그램 이름입니다. 그리고 BTW는 프로그램 측과 쉘에 동일한 인덱스가 있습니다.
나는 이것이 초기 단계의 편의 트릭이라고 생각하고 다른 답변에서 볼 수 있듯이 매우 편리했기 때문에이 전통은 계속되어 API로 설정되었습니다.
답변
기본적으로 argv에는 프로그램 이름이 포함되어 있으므로 다음과 같은 오류 메시지를 작성할 수 있습니다 prgm: file: No such file or directory
.
fprintf( stderr, "%s: %s: No such file or directory\n", argv[0], argv[1] );