bash -c를 호출하면 소스가 작동하지 않는 이유는 무엇입니까?

bash -c를 호출하면 소스가 작동하지 않는 이유는 무엇입니까?

특정 환경을 처리하기 위한 스크립트를 얻기 위해 명령을 실행하고 싶습니다. 현재 쉘에서 변수를 가져오는 대신 실행 전의 변수입니다.

테스트 환경

export test=1

이러한 명령 중 어느 것도 환경을 반영하지 않습니다. 바꾸다:

a) 이것이 효과가 없을까요? 새 셸에서 이 명령을 실행하고 출력을 다시 가져오는 것은 아닌가요?

$ bash -c "source test.env && echo $test"

b) 여기에서는 test.env를 실행하고 exec를 사용하여 동일한 프로세스에서 echo $test를 실행하려고 합니다.

$ bash -c "./test.env && exec echo $test"

c) 결국 나는 순열이 가능했기 때문에 이것을 시도했습니다. 그러나 test.env 및 echo 명령은 별도의 프로세스로 실행됩니다.

$ bash -c "./test.env && echo $test"

환경에서 어떻게 작동하게 할 수 있습니까? 두 번째 명령을 실행하기 전에 얻은 변수입니까?

답변1

$첫 번째 명령에서 달러 기호를 이스케이프 해야 합니다 . 그렇지 않으면 bash명령이 실행되기 전에 달러 기호가 확장됩니다.

$ bash -c "source test.env && echo \$test"

또는 큰따옴표 대신 작은따옴표를 사용해야 합니다.

$ bash -c 'source test.env && echo $test'

답변2

ENV단순히 프로세스를 실행하기 전에 설정을 처리하고 현재 셸에 영향을 주지 않는 것이 목표라면 실행 파일을 exec실행하는 것이 bash가장 효율적인 접근 방식이 아닐 수 있습니다.

( . /dev/fd/4 && echo "$i" ) 4<<\SCRIPT
    i='i is set here in the subshell'
#END
SCRIPT

echo ${i?but i isnt set here because it was set in the subshell}

산출

i is set here in the subshell
sh: line 5: i: but i isnt set here because it was set in the subshell

물론 heredoc 파일 설명자에 대한 링크를 일반 파일로 바꿀 수 있습니다. 저는 단지 그것을 시연하기 위해 사용했습니다.

하지만 만약 당신이하다 execbash내장 셸 대신 외부 프로세스(예: 또는 다른 프로세스)를 사용하는 경우 하위 셸이 필요하지 않습니다.

one=1 two=2 \
    bash -c 'echo "${cmd=This is command #}$one" 
             echo "${cmd}$two"'
echo "${one?this var was only set for the execed ENV}"

산출

This is command #1
This is command #2
sh: line 2: one: this var was only set for the execed ENV

외부 프로세스인 경우 bash또는 기본적으로 tdin을 허용하는 다른 -sPOSIX 호환 셸에서 스크립트를 파일에 직접 작성할 수 있습니다 |pipe.

{ echo PS1=
  echo 'echo "$PS1"'
  cat /etc/skel/.bashrc
  echo 'echo "$PS1"'
} | bash
echo "${PS1:?unset here again}"

산출

#blank line from first echo
[\u@\h \W]\$
sh: line 7: PS1: unset here again

답변3

$test작성된 대로 명령이 전달되기 전에 쉘이 확장됩니다. ' 대신 을 사용하면 이런 일이 발생하는 것을 방지 할 수 있습니다 ".

bash -c 'source test.env && echo $test'

관련 정보