왜“set”이라는 프로그램이 실행되지 않습니까?


10

다음과 같은 간단한 C 프로그램을 만들었습니다.

int main(int argc, char *argv[]) {

    if (argc != 5) {
       fputs("Not enough arguments!\n", stderr);
       exit(EXIT_FAILURE);
    }

그리고 etc / bash.bashrc 에서 PATH를 다음 과 같이 수정했습니다 .

PATH=.:$PATH

이 프로그램을 set.c로 저장하고 다음과 같이 컴파일하고 있습니다.

gcc -o set set.c

폴더 안에

~/Programming/so

그러나 내가 전화하면

set 2 3

아무 반응이 없습니다. 표시되는 텍스트가 없습니다.

부름

./set 2 3

예상 결과를 제공합니다

나는 전에 PATH에 문제가 없었습니다.

which set

을 반환합니다 ./set. 따라서 PATH가 올바른 것 같습니다. 무슨 일이야?


10
'.'를 추가하는 것은 비교적 위험합니다. 당신의 경로에. 로컬 디렉토리에서 무언가를 실행할 때 ./를 사용하거나 실행 파일을 ~ / bin /와 같은 잘 알려진 디렉토리로 옮기는 것이 좋습니다.
TREE

7
test기본적으로 같은 이유로 테스트 프로그램을 호출하는 것도 좋지 않습니다 . test쉘도 내장되어 있습니다.
Jonathan Leffler

@JonathanLeffler 그리고 아직 빠른 테스트를 위해서는 프로그램을 호출하는 test것이 합리적입니다. 물론 당신이 그것을 넣을 때까지 당신은 PATH정말로 다른 이름을 생각해 냈을 것입니다. 그리고 프로그램을 넣을 때까지 어쨌든 프로그램 PATH을 호출해야 ./test합니다. 따라서 test하루가 끝나기 전에 삭제하려는 빠른 테스트라면 프로그램 이름을 사용하는 것이 좋습니다.
kasperd

1
@kasperd : 내가 아는 한, 빠른 테스트 프로그램의 일반적인 이름은 foo입니다.
hmakholm

이름을 지정하면 ls존재하는지 확인할 때마다 실행됩니다 (그러나 질문에서했던 것처럼 경로를 수정하는 경우에만).
ctrl-alt-delor

답변:


24

대신에 사용 which하는, 당신이 그것을 가장 필요로 할 때 작동하지 않습니다 , 사용은 type당신이 명령을 입력 할 때 실행을 결정하기 위해 :

$ which set
./set
$ type set
set is a shell builtin

쉘은을 검색하기 전에 항상 내장을 찾고 $PATH있으므로 설정 $PATH이 도움이되지 않습니다.

실행 파일의 이름을 다른 것으로 바꾸는 것이 가장 좋지만 할당에서 프로그램의 이름을 지정해야하는 경우 set쉘 함수를 사용할 수 있습니다.

$ function set { ./set; }
$ type set
set is a function
set ()
{
    ./set
}

(이에 서 작동 bash하지만 다른 쉘 ksh은 허용하지 않을 수 있습니다. 더 이식성있는 솔루션에 대해서는 mikeserv의 답변을 참조하십시오.)

이제 타이핑 set하면 "set"이라는 함수가 실행 ./set됩니다. GNU bash는 내장을 찾기 전에 함수를 찾고,를 검색하기 전에 내장을 찾습니다 $PATH. bash 매뉴얼 페이지의 "COMMAND EXECUTION"섹션에 이에 대한 자세한 정보가 있습니다.

builtincommand: help builtin및 설명서를 참조하십시오 help command.


3
type이상을 추천 which하지만 이유를 밝히지 마십시오. ( 왜 그런지 알지만 추천이 필요한 사람은 그렇지 않을 것입니다.)
cjm

1
@cjm 다음에 대한 전체 논문 이 있습니다 : unix.stackexchange.com/questions/85249/…
Anthony Geoghegan

매우 유익합니다. 당신은 간단한 작업을 수행 같은 겉으로는 간단한 명령을 통해 너무 많은 논란이있다 생각 없었어요
Ganea 댄 안드레이

4
@GaneaDanAndrei 주로, type대신에 사용 하고 which, 프로그램 이름을 "set"으로 지정하지 말고 function set { ./set; }아마도 피해야 할 추악한 해킹이라는 것을 깨달으십시오 .
yellowantphil

11

setbash (그리고 아마도 대부분의 다른 쉘)에 내장되어 있습니다. 이것은 bash가 함수를 찾을 때 경로를 검색하지도 않음을 의미합니다.

부수적 .으로 보안상의 이유로 경로를 추가 하지 않는 것이 좋습니다. 예 cd를 들어 /tmp다른 사용자가 실행 파일을 추가 한 후 종료 한다고 상상해보십시오 /tmp/cd.


2
네, 우리의 선생님 세력 순서는 ,, 프로그램 "을 제시하면서 전문가가 아닌 보이지 않는 것을 바보 같은 생각 그는 성적을 아래로 완료되지 않은 경우..
Ganea 댄 안드레이

1
훌륭한 교사를위한 브라우니 포인트 :(
klimpergeist

4
cd은 셸이 내장되어 있으므로와 같은 이유로 예제가 작동하지 않습니다 set.
Emil Jeřábek

15
./foo프로그램을 호출하기 위해 사용 하는 것은 전문적입니다. .$ PATH에없는 이유를 이해했음을 나타냅니다 . 선생님이 틀렸고 내가 그렇게 말했다고 말할 수도 있습니다.
zwol

10

set하지 내장 명령, 그것은이다 POSIX 특수에 내장 . 검색 $PATH되지 않고, 함수 이름을 검색하지 않는 등의 명령 검색에서 표준으로 지정되는 몇 가지 기본 제공 명령이 있습니다 . POSIX 표준 에서는 특수 하지 않은 대부분의 기본 제공 명령 이 실제로 필요 합니다. 셸 에서 자체 내장 프로 시저를 실행 $PATH 하기 전에 발견하십시오 . 이것은 사실이다 echo대부분의 다른 사람들과 (하지만이 점에서 영광되는 표준이 과거에 오픈 그룹 메일 링리스트에서 경합의 문제가 있었는지) ,하지만 하지set, trap, break,return, continue, ., :, times, eval, exit, export, readonly, unset, 또는 exec.

이들은 모두 쉘의 예약 이름이며 명령 검색에 대한 선호 순서 이외의 특수 속성도 있습니다. 예를 들어, 표준 호환 쉘에서 해당 이름으로 쉘 기능을 정의 할 수 없습니다. 이것은 좋은 일입니다 -사람들이 휴대용 스크립트를 안전하게 작성할 수있게 합니다. 이들은 숙련 된 스크립트 작성자가 자신의 환경에서 안전하고 안정적인 발판을 구축 할 수있는 기본 명령입니다. 이 네임 스페이스를 침범하는 것은 권장 되지 않습니다.

그러나 당신이 그것을 침공하기를 원한다면, 당신은 그렇게 할 수 있습니다 alias. 쉘 확장 순서 는이 해결 방법을 가능하게합니다. alias명령을 읽는 동안가 확장 되었으므로 set정의에서 이름 을 바꾸는 모든 것이 올바르게 확장되므로 해당 이름 중 하나로 확장해서는 안됩니다.

그래서 당신은 할 수 있습니다 :

alias set=./set

... 잘 작동합니다.


3

문제는 set셸 내장이며 최상의 해결책은 실행 프로그램에 다른 이름사용하는 것 입니다.

또한 지난 주에 동일한 이름의 셸 내장 대신 시스템 명령실행 하는 방법에 대한 질문을 받았으며 수락 한 솔루션은 다음을 통해 명령을 실행하는 것입니다 env.

env set 2 3

사용하려는 명령이 현재 디렉토리에 있음을 이미 알고있는이 특별한 경우 .에는 현재 작업 디렉토리를 나타내는 데 사용하여 경로를 입력하여 실행 파일을 직접 실행하는 것이 좋습니다 .

./set 2 3

위의 솔루션은 모두 쉘에 구애받지 않습니다. 즉, 사용중인 쉘에 관계없이 작동합니다.

command내장 사용과 같은 제안 은 Bash에서 작동하지 않습니다.이 기능 은 쉘 기능 이 실행되는 것을 막 습니다. 문서화되어 있지는 않지만 사용하면 command키워드 도 억제 한다는 것을 알았습니다 . 그러나, 쉘에 대해 동일한 작업을 수행하지 않습니다 내장 명령set. 내가 이해하는 command것처럼 zsh와 같은 다른 쉘과 함께 작동 할 수 있습니다.

또한, 같은 트릭 \set이나 "set"또는 'set'배쉬 내장 명령에 대한 작업을하지 않습니다 - 그들은 대신에 실행 파일을 실행하는 데 유용하지만 별칭 또는 쉘 키워드를 .

참고 :이 답변은 원래 Eric의 답변에 대한 의견으로 시작되었지만 의견에 맞추기에는 너무 커졌습니다. PATH 사용을 권장하고 type추가하지 않는 다른 답변이 좋습니다 ..

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