Bash 스크립트에서 변수 할당이 작동하지 않습니다.

Bash 스크립트에서 변수 할당이 작동하지 않습니다.

문제가 있어서 쉘 스크립트를 사용하여 프로그램을 작성해야 했기 때문에 Linux에 관한 책을 펴고 Bash 스크립트에 대한 장이 있었습니다. 명령을 만났을 때 명령을 테스트하기 위해 테스트 스크립트를 작성하는 것이 좋은 생각처럼 보였지만 첫 번째 스크립트는 작동하지 않았고 다른 명백한 방법으로 변경해도 문제가 해결되지 않았습니다.

예제에 표시된 스크립트는 다음과 같습니다.

#!/bin/bash
count=10
nextcount=$count + 1
echo $count
echo $nextcount

이 스크립트를 실행한 결과는 무엇입니까?

[Carl@localhost bin]$ testscript
10
11

그러나 실제 결과는

[Carl@localhost bin]$ testscript
/home/Carl/bin/testscript: line 3: +: command not found
10

오류 메시지는 "+" 기호가 더하기 연산자가 아닌 명령으로 해석됨을 나타냅니다.

"+" 기호 주위의 공백을 제거하면 스크립트가 다음과 같이 됩니다.

#!/bin/bash
count=10
nextcount=$count+1
echo $count
echo $nextcount

[Carl@localhost bin]$ testscript
10
10+1

11을 얻기 위해 10에 1을 더하는 대신, 3행의 명령문은 "10", "+" 및 "1"을 연결합니다.

line3을 읽도록 변경하거나 nextcount=$count +1아무 nextcount=$count+ 1효과가 없습니다.

스크립팅 교과서의 첫 번째 예에서 해결 불가능한 문제를 찾는 일이 일어나서는 안 됩니다. 내가 미쳐가는 걸까?

답변1

항상 그렇듯이 쉘에서 할당하십시오.확실히공백을 허용합니다(참조:쉘 스크립트에서 변수 할당의 공백var=foo bar): 명령을 실행 bar하고 var로 설정하는 것과 같은 것입니다 foo. 또는 귀하의 경우 명령은 셸에 특별한 의미가 없으므로 +괜찮습니다 (어쨌든 이 경우는 아님). +또한 더하기 기호는 일반 문자이므로 var=1+1오른쪽을 string 으로 처리합니다 . 1+1특별한 의미(예: ;, 또는 ()가 있는 경우 인용해야 합니다.

쉘에서 산술을 수행하는 표준 방법은 확장이므로 $(( ... ))숫자를 추가하고 변수에 할당하려면 다음을 사용하십시오.

anothervar=$((var + 1))

Bash/ksh/zsh를 사용하고 있고 일정한 반복 횟수만큼 반복하려는 경우 다음을 사용할 수 있습니다.

for (( i = 0; i < 10 ; i++)); do something ; done

( for i in {1..10}또한 가능하지만 Bash에서는 중괄호 확장 내부에서 변수 확장이 작동하지 않습니다.)

답변2

산술 표현식 구문을 사용하여 수학 연산을 수행합니다.

count=10
(( nextcount = count + 1 ))

답변3

다음 명령을 사용하여 표시된 것과 유사한 작업을 수행할 수 있습니다 declare -i.

declare -i nextcount
nextcount=$count+1

변수 선언 nextcount정수 속성을 가진 변수를 선언합니다.산술 평가할당될 때마다 자동으로 실행됩니다. ( help declarebash에서 실행하거나이봐더 알아보기. ) 이것은 표준 POSIX 쉘 기능은 아니지만 bash는 이를 지원합니다.

declare이 작업에는 명령을 즉시 실행할 필요가 없습니다 . 그렇다면 declare다음과 같은 명령으로 수행하는 것이 좋습니다.

declare -i nextcount=$count+1

정수 합계를 포함한 모든 산술 표현식산술 연산자지원됩니다. 연산자가 셸에서 다른 방식으로 다르게 해석될 위험이 있는 경우 이를 방지하기 위해 표현식을 인용할 수 있습니다. 변수에 텍스트를 할당한다는 점을 기억하세요. 해당 텍스트에 대한 산술 평가를 수행하세요. 또 다른 예로, 이 명령은 다음 $x으로 확장됩니다 13.

declare -i x='2 * 7 - 1'

공백을 제거하더라도 인용하고 싶을 것입니다. *그렇지 않으면 다음과 같이 해석될 수 있기 때문입니다.전반적인 상황, 방아쇠파일 이름 확장자. 여전히 주변 공간이 있을 수 없습니다 =.

그러나 일반적으로 이 작업을 수행하지 않을 수도 있습니다.일반적으로 사용하기가 더 간단하고 우아하며 읽기 쉽습니다.산술 확장(와 함께 $) 또는산술 평가(아니요 $) 반대로, 다른 답변에서 알 수 있듯이. 나는 당신이 그것을 좋아하도록 장려하기 위해 여기에 표시된 방법을 꺼낸 것이 아니라 주로 당신의 책에 표시된 것처럼 실제로 쉘 산술을 수행하는 것과 가장 가깝기 때문입니다.

산술 표현식 - 쉘 산술을 사용하여 평가되는 표현식을 의미합니다. 이는 $(( ))or 안에 있기 때문에 (( ))주위에 =공백을 사용할 수 있습니다. 구문적으로 =명령 내에서는 ((count = 10))명령 내에서와 다르게 작동합니다.=count=10


x정수 속성( )이 있는 경우 declare -i x다음과 같은 코드를 작성하여 여러 변수에 값을 할당할 수도 있지만 혼란스럽기 때문에 권장하지 않습니다.

x=y=z=10

그것이 무엇인지 궁금하다면 여기에 힌트가 있습니다. 동일한 일을 합니다:

x='y = z = 10'

그러면 문자열 y = z = 10(또는 첫 번째 예에서는 y=z=10)이 에 할당됩니다 x. 최소한 x정수 속성을 갖는 것이 중요합니다. 이런 경우라고 가정하면 텍스트는 산술 표현식으로 평가됩니다. 하위 표현식은 에 z = 10할당되지만 해당 하위 표현식에는 에 할당되는 값도 있습니다 . 저것10z10y가득한표현식은 ystill 값을 갖는 쌍에 대한 할당입니다 10.

첫 번째 것은 =일반적인 쉘 변수 할당을 수행하는 반면 다른 것은 산술 할당 연산자입니다. 이것은아니요두 번째 형식은 특별합니다(참조로 공백을 포함할 수 있음). 에서 x=y=z=10첫 번째 es는 동일한 목표를 달성하기 위해 사용하기는 하지만 다른 두 개와 다른 의미를 =갖습니다 . =이는 혼란스러울 수 있습니다. 실험적인 목적으로 대화형으로 작성되지 않는 한 이와 같은 내용을 작성하지 않는 것이 좋습니다. 대신 다음 명령을 작성할 수 있습니다.

((x = y = z = 10))

이것은 간단한 산술 평가입니다. 세 기호는 모두 =산술 할당 연산자입니다. 변수의 일부 또는 전체를 정수 속성(제가 자주 주장하는 방식)으로 선언하는 경우에도 문제가 없지만 그럴 필요는 없습니다.


마찬가지로 bash에는 +=일반적으로 텍스트를 추가하는 연산자가 있습니다.

$ x=foo
$ x+=bar
$ echo "$x"
foobar

(일부 행의 선행 문자 $는 프롬프트입니다. bash에 제공하는 입력과 생성되는 출력을 구별하기 위해 여기에 포함합니다.)

그러나 변수에 할당된 속성은 +=수행되는 작업에 영향을 미칩니다. +=일반적으로 인덱스 배열을 확장하는 데 사용됩니다.

$ a=(foo bar baz)
$ a+=(quux)
$ echo "${a[@]}"
foo bar baz quux

정수 속성이 있는 변수가 with 에 할당되면 +=내부 추가가 수행됩니다.

$ declare -i y=7
$ y+=2
$ echo "$y"
9

+=그러나 Bash에는 산술 연산자 도 있으므로 대부분의 경우 사용을 권장합니다. 즉, y값을 저장 하면 2다음과 같이 작성하여 값을 2씩 증가시킬 수 있습니다 y.

((y += 2))

또한 다른 전통적인 복합 할당 연산자(C에 존재하는 연산자)도 있습니다. 예를 들어 내가 원한다고 해보자.줄이다y에 3을 곱합니다. 이것은 작동하지 않습니다:

$ y-=3
y-=3: command not found

하지만 이것은 작동합니다:

$ ((y -= 3))
$ echo "$y"
6

y또는 새 값을 변경하고 인쇄하여 이렇게 할 수도 있습니다 .

$ echo "$((y -= 3))"
6

관련 정보