나는 사용한다생선 껍질그리고 물고기가 읽을 수 없는 sh 호환 구문을 사용하여 작성된 일부 쉘 스크립트를 "가져오기"를 바랍니다. 예를 들어, 많은 소프트웨어에서는 유용한 환경 변수를 내보내기 위해 일부 셸 스크립트를 얻을 것으로 기대합니다.
# customvars.sh
FOOBAR=qwerty
export FOOBAR
로컬 변수와 함수 정의를 보존하는 데 관심이 없다면 한 가지 해결 방법은 exec를 사용하여 현재 프로세스를 /bin/sh로 바꾼 다음 다시 낚시로 돌아가는 것입니다.
# We start out on fish
exec /bin/sh
# Running a POSIX shell now
. customvars.sh
exec /usr/bin/fish
# Back on fish
echo $FOOBAR
이 패턴을 일부 함수에 저장할 수 있는 한 줄로 줄이는 방법이 있습니까? 내가 하려고 하면
exec /bin/sh -c '. vars.sh; /usr/bin/fish'
대화형 물고기 프롬프트로 돌아가지 않고 터미널 에뮬레이터 창이 즉시 닫힙니다.
답변1
문제는 .
특수 내장 함수를 호출하는 방법입니다.
exec /bin/sh -c '. vars.sh; /usr/bin/fish'
에서 sh
인수에 가 포함되어 있지 않으면 /
에서 .
파일을 검색합니다 $PATH
. 따라서 위에서는 예상한 대로 현재 디렉터리 대신 검색 vars.sh
합니다 $PATH
.
게다가 .
,특별한내장된 오류로 인해 쉘이 종료되므로(대화형이 아닌 경우) 다음 명령(여기 fish
)이 실행되지 않습니다. 이것이 바로 터미널 에뮬레이터 창이 프롬프트 없이 사라지는 이유입니다 fish
.
이는 .
as 를 호출하여 방지할 수 있습니다 command .
.특별한속성특별한내장된 기능.
bash
sh
POSIX 모드(GNU 프로젝트 구현)가 아닐 때의 동작은 이와 관련하여 다릅니다(as 및 sh
nor with가 호출되지 않고 --posix
환경에 POSIXLY_CORRECT=
nor가 포함되지 않은 경우 SHELLOPTS=posix
).
bash
는 .
실패 시 쉘이 종료되지 않으며, $PATH
.
vars.sh
어쨌든 POSIX 모드 여부에 관계없이 현재 디렉터리에 있으려면 ./vars.sh
구문이 필요합니다. 그래서 그렇습니다
exec sh -c 'command . ./vars.sh; exec fish'
답변2
개인적으로 나는 다른 접근 방식을 취하겠습니다. 아마도 다른 이유로 Bourne 유형 형식 파일이 필요할 것입니다. 형식을 동적으로 변경하여 물고기에서 가져오는 것은 어떨까요? 그것은 다음과 같습니다:
source (sed -nr 's/(.+)=(.+)/set \1 \2/p' file | psub)
위의 물고기는 다음과 같습니다.
source <(sed -nr 's/(.+)=(.+)/set \1 \2/p' file)
예를 들어:
> cat file
foo="baz"
export foo
> source (sed -nr 's/(.+)=(.+)/set \1 \2/p' | psub)
> echo $foo
baz
참고: 이는 소스 스크립트가 변수(질문에 명시된 대로)와 한 줄에 하나의 변수 정의만 설정한다고 가정합니다. 더 복잡한 작업의 경우 이 접근 방식이 작동하지 않습니다.