bash 스크립트 내에서 bash 함수를 정의하고 command 다음에 연결하려고 할 때 동일한 스크립트에서 이를 사용하는 데 문제가 있습니다 script
.
최소한의 작업 예는 다음과 같습니다. my_script.sh
다음을 포함하는 이라는 파일이 있습니다 .
#!/bin/bash
my_function () {
echo "My output"
}
my_function
script my_log.log -c my_function
실행 중 반환
My output
Script started, output log file is 'my_log.log'.
bash: line 1: my_function: command not found
Script done.
my_function
왜 단독으로는 인식되는데 연결 후에는 인식되지 않는지 이해가 되지 않습니다 script
.
누군가 그것을 설명하고 해결책을 제시할 수 있습니까?
답변1
여기서 문제는 함수가 스크립트 내에만 존재하지만 실행하는 명령이 script
새 셸(경로가 저장된 쉘 $SHELL
또는 /bin/sh
기타 쉘)을 호출한다는 것입니다. 새 쉘은 사용자가 함수를 정의하지 않는 한 함수에 대해 알지 못합니다.
쉘 bash
지원출구환경에 대한 기능. sh
해당 환경에서 실행되는 bash에 대한 다른 모든 호출(bash로 실행되는 호출도 포함)은 이러한 정의를 가져옵니다 .
함수를 내보내려면 다음을 수행해야 합니다.
export -f my_function
help export
셸에서 보기 bash
:
$ help export
export: export [-fn] [name[=value] ...] or export -p
Set export attribute for shell variables.
Marks each NAME for automatic export to the environment of subsequently
executed commands. If VALUE is supplied, assign VALUE before exporting.
Options:
-f refer to shell functions
-n remove the export property from each NAME
-p display a list of all exported variables and functions
An argument of `--' disables further option processing.
Exit Status:
Returns success unless an invalid option is given or NAME is invalid.
그런 다음 해야 할 일은 인터프리터를 script
실행 bash
한 후 명령줄이 전달되었는지 확인하는 것입니다 -c
. 올바른 변수 값을 전달해야 합니다 $SHELL
.
SHELL=$BASH script -c myfunction
답변2
보충하다@terdon의 답변bash
, (ksh, mksh, zsh) 이외의 Korn과 유사한 셸을 지원하는 것 외에도 typeset -f
또는 bash
함수 내보내기 기능의 함정(아래 참조)을 피하기 위한 경우 몇 가지 대안을 제안합니다.
실행된 셸에서 정의한 동일한 함수의 경우 script
셸 코드가 전달되기 전에 함수 정의를 포함할 수 있으며 script -c
다음을 사용하여 얻을 수 있습니다 typeset -f
.
SHELL=/same/shell/as/running/the/current/script script -c "
$(typeset -f myfunc)
myfunc"
script
함수를 정의한 다음 호출하여 시작되는 새 셸이 시작되는 곳입니다 .
또는 함수 본문을 환경 변수 1에 전달하고 script
해당 변수의 내용을 평가하여 셸을 시작합니다.
SHELL=/same/shell/as/running/the/current/script \
MYFUNC_DEFINITION="$(typeset -f myfunc)" script -c '
eval "$MYFUNC_DEFINITION"
myfunc'
(이 접근 방식은 모든 사람이 출력에서 볼 수 있도록 명령줄 인수에 함수 본문을 노출하지 않는다는 장점이 있습니다 ps
.)
export -f
비교 시 장점은 다음과 같습니다(bash에만 국한되지 않음).
- 그러면 함수는 해당 환경에서 시작될 수 있는 다른 셸이 아닌 필요한 셸에만 노출됩니다.
bash
extglob
함수가 연산자를 사용하는 경우 이 옵션을 활성화 하지 않으면 함수 가져오기가 실패합니다.extglob
앞으로함수를 가져왔습니다. 우리의 접근 방식을 사용하면 함수 정의를 가져올 시기를 선택한 다음shopt -s extglob
앞에 함수 정의를 추가할 수 있습니다. 하지만 with를 사용하여 내보낸 함수의 경우export -f
옵션을 초기에 설정할 수 있는 유일한 방법은 여기서 옵션이 아닌 with를 사용하는 것입니다. 심지어 (모든 통화에 영향을 미치기 때문에 위험합니다) 작동하지 않습니다.extglob
bash -O extglob
script
env BASHOPTS=extglob script -c ...
bash
1 사실 그게 bash
전부입니다 export -f
. 심지어는 매우 안전하지 않은 방식으로 이를 수행하기도 했는데, 이는 몇 년 전에 헤드라인을 장식했던 매우 불쾌한 취약점의 원인이었습니다. .