태그 보관물: shell-builtin

shell-builtin

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

다음과 같은 간단한 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가 올바른 것 같습니다. 무슨 일이야?



답변

대신에 사용 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.


답변

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

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


답변

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

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

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

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

alias set=./set

… 잘 작동합니다.


답변

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

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

env set 2 3

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

./set 2 3

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

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

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

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


답변