Bash에서 명령 앞에 변수를 설정하는 것이 합법적인 이유는 무엇입니까?

Bash에서 명령 앞에 변수를 설정하는 것이 합법적인 이유는 무엇입니까?

방금 다음과 같은 몇 가지 답변을 발견했습니다.구분된 텍스트 파일을 구문 분석하는 중...다음 구조를 사용하십시오.

while IFS=, read xx yy zz;do
    echo $xx $yy $zz
done < input_file

여기서 IFS변수는 명령 앞에 설정됩니다 read.

나는 읽고 있었다배시 참조그러나 이것이 왜 합법적인지 이해하지 못합니다.

나는 노력했다

$ x="once upon" y="a time" echo $x $y

bash 명령 프롬프트에서 에코를 받지 못합니다. 누군가 참조에서 이 구문이 정의되어 IFS 변수를 이런 방식으로 설정할 수 있도록 알려줄 수 있습니까? 이것은 특별한 경우인가요? 아니면 다른 변수에도 비슷한 작업을 수행할 수 있나요?

답변1

관련 정보는 다음에서 확인할 수 있습니다.매뉴얼 페이지BASH 관리자가 제공했습니다(마지막 확인: 2020년 8월). 쉘 구문 섹션, 단순 명령 상태(강조 추가):

간단한 명령은선택적 변수 할당 순서 그다음 공간 분리 단어 및 리디렉션, 제어 연산자에 의해 종료됩니다. 이것첫번째 단어실행할 명령을 지정하며 인수 0으로 전달됩니다. 나머지 단어는 호출된 명령에 인수로 전달됩니다.

따라서 원하는 변수를 전달할 수 있습니다. echo변수가 셸에서 설정되지 않고 명령에 전달되기 때문에 예제가 작동하지 않습니다 . 껍질이 팽창 $x하고$y 앞으로명령을 호출하십시오. 예를 들어 다음과 같이 작동합니다.

$ x="once upon" y="a time" bash -c 'echo $x $y'
once upon a time

답변2

정의된 변수는 분기된 프로세스의 환경 변수와 같습니다.

당신이 달리면

A="b" echo $A

그런 다음 bash는 먼저 다음 $A으로 확장된 ""다음 실행됩니다.

A="b" echo

올바른 방법은 다음과 같습니다.

x="once upon" y="a time" bash -c 'echo $x $y'

작은따옴표를 참고하세요. bash -c그렇지 않으면 위와 같은 문제가 발생하게 됩니다.

따라서 bash 내장 "read" 명령이 환경 변수에서 IFS를 찾아서 찾기 때문에 루프 예제는 적법합니다 ,.

for i in `TEST=test bash -c 'echo $TEST'`
do
  echo "TEST is $TEST and I is $i"
done

인쇄할 것이다TEST is and I is test

마지막으로 구문상 for 루프에는 문자열이 필요합니다. 그래서 백틱을 사용하여 명령으로 바꿔야 했습니다. 그러나 while 루프에는 IFS=, read xx yy zz.

답변3

man bash

환경

[...] 위의 매개변수에 설명된 대로 간단한 명령이나 기능의 환경은 앞에 매개변수 할당을 추가하여 일시적으로 향상될 수 있습니다. 이러한 지정문은 명령으로 표시되는 환경에만 영향을 미칩니다.

변수는 변수 할당 전에 확장됩니다. 분명한 이유로 var=x그 반대가 사실이지만 var=$othervar그렇지 않습니다. 즉, $x사용 가능해지기 전에 귀하의 것이 필요합니다. 그러나 그것은 주요 문제가 아닙니다. 주요 문제는 명령줄은 쉘 환경에서만 수정할 수 있지만 할당은 쉘 환경의 일부가 되지 않는다는 것입니다.

기능이 혼란스럽습니다. 명령줄을 바꾸고 싶지만 변수 정의를 명령 환경에 넣습니다. 명령줄 대체는 쉘에서 수행되어야 합니다. 호출되는 명령은 명시적으로 이 환경을 사용해야 합니다. 이것이 수행되는지 여부와 방법은 명령에 따라 다릅니다.

이 사용법의 장점은 쉘 환경에 영향을 주지 않고 하위 프로세스에 대한 환경을 설정할 수 있다는 것입니다.

x="once upon" y="a time" bash -c 'echo $x $y'

예상한 대로 이 경우 두 기능이 결합되어 있습니다. 명령줄 대체는 호출 셸이 아니라 하위 프로세스 셸에 의해 수행됩니다.

답변4

더 큰 그림을 추구하고 싶다”합법이다"

대답: 이 방법으로 프로그램을 호출하거나 해당 호출에 대해 특정 변수와 함께 변수만 사용할 수 있습니다.

예를 들어 "db_connection"이라는 데이터베이스 연결 매개변수가 있고 일반적으로 테스트 데이터베이스 연결 이름으로 "test"를 전달합니다. 실제로 이를 기본값으로 설정할 수도 있으며 명시적으로 전달할 필요가 없습니다. 그러나 때때로 ci 데이터베이스를 사용하고 싶을 때가 있습니다. 따라서 호출된 프로그램에서 사용되는 "ci"로 인수를 전달합니다.저것데이터베이스 매개변수는 모든 데이터베이스 호출에 사용되는 데이터베이스의 이름 역할을 합니다. 다음 실행에서는 메서드를 반복하지 않고 프로그램만 호출하면 변수는 이전 기본값으로 돌아갑니다.

관련 정보