올바른 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.