"소스"를 사용하여 스크립트를 실행하는 전략을 잊으셨나요?

"소스"를 사용하여 스크립트를 실행하는 전략을 잊으셨나요?

대화형 bash 셸의 상태에 액세스하는 스크립트를 작성하고 싶습니다. 예를 들어 스크립트에는 jobs, 및 dirspushd같은 명령이 포함되어 있습니다 popd. 그래서 내 전략은 source스크립트를 실행할 때 스크립트를 셸에 넣는 것입니다. 그러나 나는 source이것을 얼마나 빨리 깨닫게 되는지에 따라 종종 이것을 잊어버리고 한동안 혼란스러워진다. 네, 제가 직접 대본을 썼습니다.

저처럼 건망증이 심한 사람들을 위한 모범 사례가 있나요? 예를 들어, 다음 중 좋은 아이디어가 있습니까?

  1. source예를 들어 어떤 방식으로든 스크립트 자체를 수정하여 입력 없이 스크립트를 어떻게 실행할 수 있습니까 ?
  2. 스크립트 자체에서 source이를 상기시키려면 어떻게 해야 합니까? 예를 들어,

    • 접두사를 사용하여 Source_Me스크립트 파일의 이름을 바꾸시겠습니까 ?
    • source아니면 스크립트가 호출되었는지 감지 하고 그렇지 않은 경우 오류 메시지를 출력하기 위해 스크립트 내부에 사용되는 일부 명령이 있습니까 ?
  3. 아니면 어떤 스크립트가 이를 요구하는지 기억하기 위해 더 노력해야 합니까 source?

    감사해요.

답변1

그것을 얻으면 실행 비트가 필요하지 않습니다.

스크립트를 실행 가능하게 만들지 마십시오. 그런 다음 (얻지 않고) 실행하려고 하면 실행( Permission denied)되지 않으므로 아무런 효과도 발생하지 않습니다. PATH 환경에 있는 경우 완성 가능 쉘(bash...)은 탭을 사용하여 자동 완성을 시도하지도 않습니다.

.profile이제 다음과 같은 별칭을 추가할 수 있습니다 .bashrc .

alias myscript='. /path/to/myscript'

따라서 이제부터 입력하면 myscript해당 내용을 가져와서 예상대로 실행합니다. 쉘은 별명을 자동 완성하기도 합니다.

답변2

소스 코드로 간주되는 스크립트를 실행하는 경우 오류 메시지를 인쇄하는 데 사용할 수 있는 몇 가지 전략이 있습니다.

  • 해당 이름이 스크립트 이름과 일치 하는지 확인할 수 있습니다 $0. 그렇다면 가져오지 않은 것이므로 오류 메시지를 인쇄하고 종료하세요.

    if [ "${0##*/}" = "myscript" ]; then
        echo "Don't run me, source me" >&2
        exit 1
    fi
    

    (그러면 스크립트 이름이 바뀔 때마다 업데이트를 주의해야 합니다...)

    $0허용 가능한 한도 /etc/shells인지 확인하는 변형이 있을 수 있습니다 (여기에 나열된 쉘로만 쉘 스크립트를 실행할 의무는 없습니다.

  • 스크립트가 대화형 셸에서만 사용되도록 의도된 경우 다음을 확인할 수 있습니다. 가져오기 대신 실행하면 대화형 셸에 포함되지 않습니다.

    case "$-" in
    *i*) ;;
    *) echo "Don't run me, source me" >&2; exit 1 ;;
    esac
    

답변3

스크립트 자체에서 source이를 상기시키려면 어떻게 해야 합니까?

사용자 정의 인터프리터를 만들고 source_reminder실행 가능하게 만듭니다.

#!/bin/sh
printf "%s\n" "Source me!" >&2
exit 1

그런 다음 실행 가능한 스크립트에서 사용하십시오.

#!/path/to/your/source_reminder
foo
bar
whatever

이제 소스 없이 스크립트를 실행하면 경고가 작동합니다.

내 Debian printf자체에서는 기본 알림으로 작동합니다.

#!/usr/bin/printf Source me! . %q\n
foo
bar
whatever

그러나 당연히 이런 방식으로 사용하면 표준 출력으로 인쇄되고 성공적으로 종료됩니다.

답변4

소스 스크립트여야 합니까? 함수로 만드세요. 그래서 대신

$ . something some args            # run it

가지다

$ cat define_something.sh
something() {
    commands here...
}
$ . define_something.sh            # load the function definition
$ something some args              # run the function

또는 실제 명령을 소스 스크립트에 포함하려면 함수를 사용하여 가져옵니다.

something() {
    . something "$@"
}

something foo bar그런 다음 대신 실행하십시오 . something foo bar.

물론 이 함수는 기본 셸 환경에서 위치 매개변수를 숨기므로 거기에는 아무런 영향이 없습니다. 필요한 경우 별칭을 사용할 수도 있습니다 something. . something(이것은 다음에 의해 수행되었습니다.AB의 답변.)

관련 정보