이 명령이 있는 경우:
expr 2 * 4
*
와일드카드가 평가되므로 이스케이프해야 하기 때문에 작동하지 않습니다 .
expr 2 \* 4
하지만 다음과 같은 두 가지 상황이 발생하는 경우:
let var1=2*4
var2=$((2*4))
그러면 *
와일드카드가 평가되지 않으므로 이스케이프할 필요가 없습니다.
*
위의 두 가지 경우에 와일드카드가 평가되지 않는 이유는 무엇입니까 ? 내 생각 엔 bash
and 를 사용할 때 전혀 평가되지 않은 것 같습니다 .let
$(())
이 경우 와일드카드가 평가되지 않는 다른 상황이 있습니까?
답변1
에서는 var2=2*4
공백(메타 문자)으로 인해 2
a, 일부 문자 및 4로 시작하는 파일이 pwd에 존재하지 않습니다 .
줄은 공백을 구분 기호로 사용하여 토큰으로 분할됩니다.
공백이 없습니다(이후에는 =
인용된 것으로 간주됩니다).
$ var1=2*4
그러나 그것은 그렇습니다:
$ echo 2 * 4
태그가 되어 *
확장됩니다(파일 이름 확장자로).
특수 효과에 따옴표를 사용하지 않으려면 다음을 수행하십시오 *
.
$ expr 2 \* 4
8
$ expr 2 "*" 4
8
$ expr 2 '*' 4
8
그러나 이는 다음과 같이 확장됩니다.
$ touch 2good4
$ echo 2*4
2good4
에서는 echo $((2*4))
구문 내부의 내용이 $((…))
산술 확장으로 해석됩니다. 어느 쪽이든 동일한 작업을 수행합니다(공백이 있어도).
$ echo $((2*4))
8
$ echo $(( 2 * 4 ))
8
$ echo $(( 2 * 4 ))
8
답변2
당신이 보고 있는 행동이 설명되었습니다여기에 와일드카드그리고여기는 확장용이에요그리고 man let
Bash의 매개변수 사양 페이지는 "let"을 제공하는 것을 알고 있습니다.
Bash가 자신을 볼 때 *
경로 이름 확장을 수행합니다.와는 별개로
확장이 null 결과를 반환하는 경우 이 경우 리터럴 문자열을 반환합니다.
echo 2 * 4 #echo 2, the contents of the pwd and then 4
*
미분 형식 또는 확장(수학/명령/매개변수 또는 전혀 확장 없음)을 사용하도록 지시하는 플래그가 앞에 있으면 관련 방법을 사용합니다 . 그래서
let var1=2*4 #pass the **arithmetic** argument var1=2*4 to the let command because bash knows let takes special characters (% * etc) as arguments
var2=$((2*4)) #bash parses the string as far as $ and sees an instruction to expand
#bash then sees (( the which specifies arithmetic expansion specifies
당신이 말했듯이
echo 2 \* 4 #perform no expansion
답변3
이유를 알고 싶다면 bash가 수행할 수 있는 작업과 bash가 명령을 구문 분석하는 방법을 알아야 합니다.
먼저 *가 bash에서 할 수 있는 작업은 다음과 같습니다.
파일 이름 glob의 와일드카드로
가져가다
정규식에서 0회 이상 발생
...
그리고 bash가 명령을 구문 분석하는 방법(매우 간단하고 실제로는 매우 복잡함):
매개변수 대체
명령 대체
와일드카드
...
당신이 가지고 있다고 가정a.txt b.txt현재 디렉터리에서 expr 2 * 4
매개변수 대체->명령 대체->와일드카드를 적용하면 다음과 같이 됩니다.
expr 2 a.txt b.txt 4
정답을 반환하지 않는 이유는 무엇입니까?
그러나 에서는 expr 2 \* 4
*가 문자입니다! 매개변수 대체, 명령 대체, 와일드카드는 영향을 주지 않습니다. 따라서 expr은 3개의 매개변수 2 * 4를 얻고 8을 반환합니다.
Bash 에서는 let var1=2*4
globbing 전에 산술 대체가 수행되고 globbing 이후의 명령은 입니다 let var1=8
. 현재 디렉토리에 2a4 2b4가 있고 let을 사용하지 않는다면, 그냥
var1=2*4
echo $var1
8이 아닌 2a4 2b4를 반환합니다.
에서 var2=$((2*4))
bash는 (())가 산술 연산자이기 때문에 산술 대체도 수행합니다.
첨부된:*를 산술 연산자로 사용하려면 (()) $[] 안에 유지하거나 let을 사용하세요. 예를 들면 다음과 같습니다.
((var1 = 2 * 4)) or var1=$((2 * 4))
var1=$[2 * 4]
공백이 허용됩니다!