변수를 설정하기 위해 서브쉘에서 대체

변수를 설정하기 위해 서브쉘에서 대체

원격으로 스크립트를 실행하고 표준 출력을 사용하여 변수를 채우려고 합니다. 임시 파일을 피하기 위해 이렇게 합니다.

이것이 내가 시도하는 패턴입니다.

var=$(bash <(curl -fsSkL http://remote/file.sh))
echo "var=${var}"

curl다음을 사용 하지 않고 이 패턴을 테스트하고 있습니다 cat.

var=$(bash <(cat ./local/file.sh))
echo "var=${var}"

이것~해야 한다구문적으로는 동일합니다. ./local/file.sh포함하고 있으므로 해당 값을 포함시키고 echo hello싶지만 , 아쉽게도 위를 실행한 결과는 다음과 같습니다.varhello

test.sh: command substitution: line 4: syntax error near unexpected token `('
test.sh: command substitution: line 4: `bash <(cat ./local/file.sh)'
var=

임시 파일을 사용하지 않고 어떻게 목표를 달성할 수 있나요?

답변1

bash이는 POSIX 모드에서 실행할 때 쉘이 프로세스 대체를 수행하려고 시도할 때 발생하는 오류입니다. 쉘은 bashPOSIX 모드에서 프로세스 대체를 지원하지 않습니다.

bash다음과 같은 경우 POSIX 모드에서 실행됩니다.

  1. set -o posix사용되었거나,
  2. 쉘은 다음과 같이 호출됩니다 sh.

test.sh내 직감으로는 실행 중인 스크립트가 있거나 해시뱅 라인이 sh test.sh있고 우연히 . 또 다른 가능성은 스크립트가#!/bin/shshbash아니요#!-line이 전혀 없으며 다른 방식으로 bash-as- 라고 합니다.sh

대신 test.sh스크립트가 호출되는지 확인하세요 bash.

예:

$ cat script.sh
echo hello
$ cat test.sh
var=$(bash <( cat script.sh ))
printf 'var="%s"\n' "$var"
$ bash -o posix test.sh
test.sh: command substitution: line 2: syntax error near unexpected token `('
test.sh: command substitution: line 2: `bash <( cat script.sh ))'
var=""
$ bash test.sh
var="hello"

test.shPOSIX를 사용하여 이식 가능한 방식으로 스크립트에서 이 작업을 수행하려면 다음을 수행하십시오 sh.

var=$( cat script.sh | bash )
printf 'var="%s"\n' "$var"

bash이는 표준 입력을 읽는 프로세스의 출력에 영향을 미칩니다 cat.불완전한프로세스 교체 변형과 동일합니다(표준 입력만 유지). 내부 쉘에 의해 실행되는 스크립트가 어떤 형식으로든 표준 입력에서 데이터를 읽는 경우 bash이는 중요합니다 .

쉘의 표준 입력을 별도로 유지 해야 하는 경우 bash(읽어야 하기 때문에) mktemp사용 가능하다고 가정하고 사용할 수 있습니다.

var=$( tmpfile=$(mktemp); cat script.sh >"$tmpfile" && bash "$tmpfile"; rm -f "$tmpfile" )
printf 'var="%s"\n' "$var"

나중에 명령 cat script.sh으로 대체되는 것으로 이해됩니다 .curl

파일 설명자를 다루는 데 익숙하다면 shell을 호출하기 전에 파일 설명자 3의 복사본을 표준 입력 설명자로 만들고 bash가져온 스크립트가 여기에서 읽도록 할 수도 있습니다.

var=$( exec 3<&0; cat script.sh | bash )
printf 'var="%s"\n' "$var"

그런 다음 스크립트 를 읽는 script.sh데 사용됩니다.read -u 3원래표준 입력 스트림 또는 utility <&3입력 스트림을 다른 유틸리티로 리디렉션합니다.

관련 정보