올바른 Bash 및 셸 스크립트 변수 대문자


193

나는 모든 대문자로 변수를 가진 많은 쉘 스크립트를 실행하며 항상 그것에 대해 심각한 오해가 있다고 생각했습니다. 내 이해는 관습에 의해 (아마도 오래 전에 필요에 따라) 환경 변수 가 전부라는 것입니다.

그러나 Bash와 같은 현대적인 스크립팅 환경에서는 항상 임시 변수에 대한 소문자 이름 규칙과 내 보낸 (즉 환경) 변수에 대한 대문자 이름 규칙을 선호했습니다 . 예를 들면 다음과 같습니다.

#!/usr/bin/env bash
year=`date +%Y`
echo "It is $year."
export JAVA_HOME="$HOME/java"

그것은 항상 내가 맡은 일이었습니다. 이 접근법에 동의하거나 동의하지 않는 권위있는 출처가 있습니까, 아니면 순수한 스타일 문제입니까?

답변:


262

대회 환경 변수 (함으로써 PAGER, EDITOR...) 및 내부 쉘 변수 ( SHELL, BASH_VERSION, ...) 대문자이다. 다른 모든 변수 이름은 소문자 여야합니다.

변수 이름은 대소 문자를 구분합니다. 이 규칙은 실수로 환경 및 내부 변수를 무시하지 않도록합니다.

이 규칙을 유지하면서 덮어 쓰기를 피하기 위해 UNIX 도구 또는 쉘에서 사용하는 모든 환경 변수를 알 필요는 없습니다. 변수 인 경우 소문자로 사용하십시오. 내 보내면 대문자입니다.


8
+1. 우발적 인 덮어 쓰기에 대한 좋은 지적. 언급하는 것을 잊었지만 이제는 언급 했으므로 소문자를 사용하기로 결정했다고 생각합니다.
JasonSmith 2016 년

5
대문자 변수 이름을 사용하는 주된 이유는 쉘 명령과의 충돌을 피하는 것이라고 생각했습니다. 스크립트에서 변수 'hostname'을 사용했기 때문에 최근에 서버 중 하나의 호스트 이름이 실수로 '='로 변경되었습니다.
ThisSuitIsBlackNot

25
@ThisSuitIsBlackNot 크 래피 코드를 무시하고 변수를 확장하면 접두사가 붙고 명령 이름과 혼동 할 수없는 장소에서 사용됩니다. 분명히 hostname = moo를 수행하면 문제가 생길 것입니다. 소문자 "호스트 이름"을 사용하기 때문이 아니라 올바른 할당 구문을 사용하지 않기 때문입니다. 할당은 공백없이 hostname = moo로 수행됩니다. 올바른 코드를 가정하면 변수 이름이 명령 이름과 충돌하는 것에 대해 걱정할 필요가 없습니다.
lhunath

3
내가 본 모든 교과서는 모든 쉘 변수에 대해 항상 사용자 대문자입니다. 소문자 변수 이름은 허용되지만 대문자가 규칙입니다.
브라이언 S. 윌슨

3
나는 이것을 몰랐고 방금 몇 시간을 잃었습니다. USER="username"bash 스크립트 를 사용 하는 대신 ssh 대신 일부 원격 명령을 자동화합니다 user="username". 어! 다행이다.
Gabriel Staples

28

모든 명명 규칙이 지속적으로 도움이 될 것입니다. 다음은 쉘 변수 이름 지정에 유용한 몇 가지 팁입니다.

  • 내 보낸 변수와 상수, 특히 여러 스크립트 나 프로세스에서 공유되는 경우에는 모든 대문자와 밑줄 을 사용하십시오 . 적용 가능한 경우 공통 접두어를 사용하여 관련 변수가 두드러지고 모두 대문자 인 Bash 내부 변수 와 충돌하지 않도록하십시오 .

    예 :

    • 공통 접두사로 내 보낸 변수 : JOB_HOME JOB_LOG JOB_TEMP JOB_RUN_CONTROL
    • 상수 : LOG_DEBUG LOG_INFO LOG_ERROR STATUS_OK STATUS_ERROR STATUS_WARNING
  • 단일 스크립트 또는 블록으로 범위가 지정된 모든 변수에 대해 "뱀"( 소문자와 밑줄 )을 사용하십시오.

    예 : input_file first_value max_amount num_errors

    지역 변수가 다음과 같은 환경 변수와 관계가있는 경우 대소 문자를 혼합하여 사용하십시오. old_IFS old_HOME

  • "비공개"변수 및 함수 에는 선행 밑줄 을 사용하십시오 . 이것은 라이브러리 파일 내의 파일 들이나 파일 들간에 함수가 변수를 공유해야하는 쉘 라이브러리를 작성하는 경우에 특히 중요합니다.

    예 : _debug _debug_level _current_log_file

  • 낙타 사건을 피하십시오 . 이렇게하면 대소 문자 오타로 인한 버그가 최소화됩니다. 쉘 변수는 대소 문자를 구분 합니다.

    예 : inputArray thisLooksBAD, numRecordsProcessed,veryInconsistent_style


또한보십시오:


1
이다 대회 있지만 거의 보편적으로 받아 들여진다. 낙타 사건에 대한 근거는 완전히 설득력있는 것은 아닙니다. 내 보낸 변수에 SHOUTING을 사용하는 것은 약간 논란의 여지가 있습니다.
tripleee

3
나는 그것이 일반적으로 따르는 관례라고 주장하지 않았다. 나는 대부분의 프로그래머가 쉘 스크립트에서 강력한 규칙을 따르는 것에 대해 진지하게 생각하지 않으며 내가 한 일을 기반으로 내 생각을 적어 놓을 생각을 보았습니다.
codeforester

8

쉘 변수를 환경으로 내보내려면 POSIX (Issue 7, 2018 년판) 환경 변수 정의에서 다음을 지정 하는 것이 좋습니다 .

POSIX.1-2017의 쉘 및 유틸리티 볼륨에서 유틸리티가 사용하는 환경 변수 이름은 대문자, 숫자 및 _휴대용 문자 세트에 정의 된 문자 의 밑줄 ( ) 로만 구성되며 숫자로 시작하지 않습니다.

...

소문자를 포함하는 환경 변수 이름의 네임 스페이스는 애플리케이션 용으로 예약되어 있습니다. 응용 프로그램은 표준 유틸리티의 동작을 수정하지 않고이 네임 스페이스의 이름으로 환경 변수를 정의 할 수 있습니다.


6

당신이하는 일을 해요. 권위있는 출처가 의심 스럽지만 사실상 널리 퍼져있는 사실상의 표준으로 보입니다.


1
나는 동의한다. ALL_CAPS가 추악하기 때문에 ENVIRONMENT VARIABLES를 추악하게 보이게하는 것이 좋습니다.
Slim

1
코딩 스타일에 대해서는 동의하지만 널리 퍼져 있다는 것에 동의하지 않습니다. 쉘 스크립트는 사람들이 비공식적으로 배우는 측면 언어 중 하나이므로 모든 사람들이 항상 LOCATION =이라고 말하는 것처럼 느껴집니다.cat /tmp/location.txt
JasonSmith

@jhs-나는 내가 작업해야했던 쉘 스크립트에서 운이 좋았다!
Draemon

4
"소문자를 포함하는 환경 변수 이름의 네임 스페이스는 애플리케이션 용으로 예약되어 있습니다." - POSIX IEEE 표준 1003.1-2008 8.1 절
tripleee

5

실제로, "환경 변수"라는 용어는 상당히 최근의 것으로 보인다. 1984 년에 출판 된 "The UNIX Programming Environment"라는 고전 저서에서 Kernighan과 Pike는 "쉘 변수"에 대해서만 언급합니다. 색인에는 "환경"에 대한 항목조차 없습니다!


8
나는 그것이 책의 생략이라고 생각한다. getenv (), setenv () 및 environ은 UNIX 버전 7 (1979)에서 도입되었습니다. en.wikipedia.org/wiki/Version_7_Unix
Juliano

3
그 책은 대문자 변수가 특별한 의미를 가지고 있다고 지적합니다.
ashawley 2016 년

3

그것은 매우 광범위하게 개최되는 관습 일뿐입니다. "정식적인"출처가없는 것 같습니다.


1

환경 변수와 전역 변수 모두에 ALL_CAPS를 사용하는 경향이 있습니다. 물론 Bash에는 실제 변수 범위가 없으므로 전역 (대부분 설정 및 상태 추적)으로 사용되는 변수의 상당 부분이 있으며 상대적으로 적은 로컬 변수 (카운터, 반복자, 부분적으로 구성된 문자열 및 임시)


Bash는 종종 자식 프로세스가 작업을 수행하는 모든 작업을 수행하도록 요청하기 때문에 수출되지 않은 변수를 로컬로 생각합니다.
JasonSmith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.