쉘 변수에서 물결표 확장은 어떻게 작동합니까?

쉘 변수에서 물결표 확장은 어떻게 작동합니까?

스크립트를 테스트하던 중 흥미로운 사실을 발견했습니다.

다음을 실행하면 쉘에서 수동으로 내 디렉토리를 찾을 수 있습니다.

$ ls ~/db_backups/
test1  test2
$ 

그러나 물결표를 사용하여 쉘 변수에 디렉토리 위치를 할당하면 작동하지 않습니다. 나는 작은 따옴표와 큰 따옴표를 사용하여 시도했습니다.

$ backupfolder='~/db_backups'
$ echo $backupfolder
~/db_backups
$ ls $backupfolder
ls: cannot access '~/db_backups': No such file or directory
$ 

쉘 변수 내에서 물결표 대체는 어떻게 되나요? 디렉토리 이름에 물결표를 수동으로 사용하는 것처럼 변수를 통해 디렉토리를 찾을 수 없는 이유는 무엇입니까?

답변1

물결표가 변수 확장 결과의 일부인 경우 쉘은 bash확장되지 않습니다 . ~따옴표가 없는 물결표 접두사( ~또는 현재 사용자 이름의 경우 ~+) 는 시작하거나 바로 뒤에 오는 경우에만 현재 사용자 의 홈 디렉터리로 확장됩니다 .~usernameusername=:/

귀하의 경우 변수에 할당할 때 확장을 수행하는 것이 더 쉬울 것입니다 backupfolder. 물결표를 놓으면 이렇게 됩니다.인용되지 않음(작은따옴표나 큰따옴표를 사용하지 마세요):

backupfolder=~/db_backups
ls "$backupfolder"

...또는 $HOME대신 사용하는 경우(작은따옴표 없이):

backupfolder=$HOME/db_backups
ls "$backupfolder"

두 할당 모두에서 쉘은 할당 연산자 오른쪽의 값을 db_backups현재 사용자의 홈 디렉토리에 있는 호출 경로 이름으로 확장합니다.

일반적으로 $HOME스크립트 내에서 사용하는 것이 더 쉽고 ~대화형 세션에 남겨두면 편리한 바로가기 역할을 할 수 있습니다. 이 HOME변수는 항상 다음과 같이 동작합니다.바꾸다.

답변2

~user/간단히 말해서 (또는 )은 명시적이고 따옴표가 없어야 ~/하며 변수 확장의 결과가 될 수 없습니다.

당신은 backupfolder=~/'db_backups'성공 해야합니다ls $backupfolder

긴 설명

물결표 확장이 발생할 수 있는 유일한 방법은 실제인용되지 않음 ~많으면인용되지 않음 /, 또는 문자열의 끝.

An은 echo ~cris/'one space'물결표(및 사용자 이름)를 확장하지만 실제 물결표가 없으면 ~물결표는 확장되지 않습니다. 흥미롭게도 이러한 명령에는 경로 값에 공백이 포함되어 있으므로 인용이 필요합니다 one space.

또한 이 목록 중 하나라도 확장되면(bash에서 중괄호 확장 후 확장됨):물결표 확장, 매개변수 및 변수 확장, 산술 확장 및 명령 대체실행되면(왼쪽에서 오른쪽으로 수행됨) 목록의 다른 단어는 동일한 단어에 다시 적용되지 않습니다(모두 동시에 발생함).

그런 다음 중괄호 확장(첫 번째 확장)이 목록을 통해 추가로 확장될 수 있으며, (마지막 두 확장) 단어 분할 및 경로명 확장이 이전 단계의 결과에 적용됩니다. 예를 들어, 다음과 같은 세 가지 변수가 확장됩니다.

$ echo $HIST{FILE,FILESIZE,SIZE}
/home/cris/.bash_history 2000 1000

가새 확장의 결과는 변수 확장을 통해 다시 확장됩니다. 그러나 변수 확장은 다른 확장으로 다시 확장되지 않습니다.

$ b='$((2+2))'; echo $b
$((2+2))

~user/간단히 말해서 (또는 )은 명시적이고 따옴표가 없어야 ~/하며 변수 확장의 결과가 될 수 없습니다.

산술 확장은 "한 번만 확장" 규칙에 해당되지 않습니다. 산술 확장에서는 확장이 여러 단계로 반복될 수 있습니다. 예를 들어:

$ a=b; b=c; c=d; d=23; echo $(($a))
23

내가 나열하지 않았지만 process substitution이것도 추가해야 한다는 점에 유의하세요.

관련 정보