
현재 회사의 전 직원이 작성한 일부 스크립트를 해독하려고 시도하는 동안 많은 스크립트에서 아래와 같이 일부 명령에 변수를 할당하는 다음 명령문을 발견했습니다.
CAT=cat
GREP=grep
SED=sed
스크립트 뒷부분에서 일반 명령 대신 다음 변수를 사용했음을 알 수 있습니다.
$GREP -v "^#" `dirname $0`/abcdfilename | while read line
do
<some loop operations>
done
직접 사용하는 대신 이 변수를 사용하는 것이 의미가 없습니다 grep
. 내 질문은 다음과 같습니다
- 이런 방식으로 grep이나 sed(우리의 경우)를 수행하는 데 의미가 있나요?
- 이것은 다른 사람이 이해하기 어렵게 만들려는 의도로 스크립트를 작성하려는 누군가의 결과입니까?
- 아니면 이것은 단순히 잘못된 스크립팅의 예입니까?
답변1
시스템에는 표준 명령에 대한 다양한 구현이 있습니다. Solaris 10 및 이전 버전과 마찬가지로 /bin/sh
이전 Bourne 쉘과 /usr/xpg4/bin/sh
POSIX 호환 쉘이 있습니다. 또는 OSX에서는 호출할 때 BSD sed를 사용 sed
하고 호출할 때 GNU sed를 사용합니다 gsed
. 스크립트에서 사용할 구현을 선택할 수 있습니다.
따라서 변수를 사용할 때 스크립트에서 구현을 변경하는 것이 더 쉽습니다. GNU sed를 원할 때:
SED=gsed
변수를 사용하지 않는 경우 sed
스크립트에서 의 모든 항목을 바꿔야 합니다. 쉽게 할 수는 있지만 나쁜 프로그래밍 습관으로 간주됩니다.
답변2
스크립트 전체에서 반복적으로 사용하는 거의 모든 것을 변수로 만들어야 한다는 주장이 있습니다. 왜냐하면 변수를 한 번 다시 정의하면 스크립트의 나머지 부분에 파급 효과를 줄 수 있기 때문입니다.
간단한 sed 검색/바꾸기를 사용하여 기본적으로 동일한 작업을 수행할 수 있다고 주장할 수도 있지만 많은 사용자는 검색/바꾸기를 경계합니다. 교체할 의도가 없는 항목을 실수로 교체하는 것이 그다지 어렵지 않기 때문입니다.
실제로 기존 버전에 비해 다음과 같은 개선 사항을 제안하고 싶습니다.
GREP=${GREP:-/bin/grep}
즉, GREP는 사용자가 셸에서 설정한 대로 설정되거나 설정되지 않은 경우 /bin/grep으로 설정됩니다.
이 방법으로 사용자는 'grep'을 즉시 무시할 수 있습니다.
$ export GREP=/bin/fgrep
$ ./path/to/script.sh
답변3
아마도 조기 최적화의 예일 것입니다.
그 기계에는 얼마나 많은 대안이 있습니까?어느기계는sed,grep, 그리고앗? 나는 보편적 평균이 1.0에 가깝다고 확신합니다. 특정 머신에서 두 가지 선택 사항이 주어지면 스크립트가 PATH에 있는 버전에서는 실패하고 다른 버전에서는 작동하도록 구현이 다를 확률은 얼마나 됩니까? 그런 일이 발생하면 솔루션이 스크립트나 PATH를 변경할 가능성이 더 높습니까? 스크립트를 변경하는 것이 답인 것으로 판명되면 적어도 하나의 호출을 찾을 확률은 얼마입니까?grep대신에$GREP? 데크는 간접적인 필요성과 필요한 경우 의도한 대로 작동하는 것에 대비하여 쌓여 있습니다.
나는 문화와 싸우지 않을 것입니다. 매장에서 선호하는 제품이 있다면$GREP또는/usr/bin/grep아니면 그냥grep, 나는 아마도 잘 지내기 위해 함께 갈 것입니다. 그렇지 않으면 KISS: 필요할 때까지 간접 사용을 피하세요.