원격으로 스크립트를 실행하고 표준 출력을 사용하여 변수를 채우려고 합니다. 임시 파일을 피하기 위해 이렇게 합니다.
이것이 내가 시도하는 패턴입니다.
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
싶지만 , 아쉽게도 위를 실행한 결과는 다음과 같습니다.var
hello
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 모드에서 실행할 때 쉘이 프로세스 대체를 수행하려고 시도할 때 발생하는 오류입니다. 쉘은 bash
POSIX 모드에서 프로세스 대체를 지원하지 않습니다.
bash
다음과 같은 경우 POSIX 모드에서 실행됩니다.
set -o posix
사용되었거나,- 쉘은 다음과 같이 호출됩니다
sh
.
test.sh
내 직감으로는 실행 중인 스크립트가 있거나 해시뱅 라인이 sh test.sh
있고 우연히 . 또 다른 가능성은 스크립트가#!/bin/sh
sh
bash
아니요#!
-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.sh
POSIX를 사용하여 이식 가능한 방식으로 스크립트에서 이 작업을 수행하려면 다음을 수행하십시오 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
입력 스트림을 다른 유틸리티로 리디렉션합니다.