test "${1#!}" = "$1"

sunnyncom의 이미지

쉘스크립트에서 나온 내용인데요? 어떤 의미인지요? ㅜ.ㅜ

아래와 같은 함수에서 나온 내용입니다... 사실은 제목 뿐만이 아니라... 아래 함수 전체가 이해하기 어렵네요....
설명 좀 부탁 드립니다.... ㅠ.ㅜ

disabled(){
test "${1#!}" = "$1" && op== || op=!=
eval test "x\$${1#!}" $op "xno"
}

bushi의 이미지

첫줄.

${1#!} 은 패턴매칭입니다.
$1 의 시작부분에 !가 있다면 !를 삭제합니다.
그러므로
test "${1#!}" = "$1"
는 $1 문자열이 !로 시작하는지 하지 않는지를 검사하는 코드입니다.

&& $op== 는 앞에서 행한 연산 결과가 참이면 op 변수에 "=" 을 집어넣고,
|| $op=!= 는 앞에서 행한 연산 결과가 거짓이면 op 변수에 "!=" 을 집어넣습니다.

따라서 첫줄의 뜻은
$1 의 첫 문자가 '!' 이면 op 에 "=" 을 대입하고, 그 밖의 경우엔 op 에 "!=" 을 대입

두번째 줄.

세가지가 섞여 있는데... 설명을 위해 풀면

arg=${1#!}
tmp=$(eval echo \$$arg)
ret=$(test "x$tmp" $op "xno")
return $ret

$1 의 첫문자가 '!' 이면 '!'을 떼내고,
간접참조해서 원래의 문자열을 얻어오고,
얻어온 문자열과 "no" 라는 문자열을 놓고 $op 에 정의된 연산을 해서 결과를 돌려줍니다.
x 라는 prefix 를 사용하는 이유는... (C 의 NULL 참조와 비슷한) 스크립트 문법 오류를 피할 목적입니다.
예를 들기 위해 풀어쓴 코드에서는 굳이 이렇게 할 필요가 없지만
원문대로하려면 필요합니다. eval 과 test 가 겹쳐있어서 그렇습니다.

(op 를 제외하고) 지역변수를 정의해서 써먹지 않고 저렇게 보기 힘들게 코딩하는 것은
지역변수와 전역변수가 겹쳐서 간접참조 때 오동작하는 것을 피하기 위해서 입니다.
위에 설명을 위해 풀어쓴 코드를 실제로 사용한다면 arg 나 tmp 의 값을 disable() 함수로 알아내긴 힘들겠죠.

OTL

sunnyncom의 이미지

휴~ 설명을 들어도 어렵네요...

bushi의 이미지

말보다는 코드가 더 쉽죠

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define is_equal(a, b) (strcmp(a, b) ? 0 : 1)
#define is_invert(a) (a[0] == '!')
 
int disabled(char **argv)
{
   int op = is_invert(*(argv+1)) ? (argv[1]++, 0) : 1;
   return is_equal(getenv(argv[1]), "no") == op;
}
 
int main(int argc, char **argv)
{
   printf("%sabled\n", disabled(argv) ? "dis" : "en");
   return 0;
}

[bushi@rose net]$ gcc -o disabled disabled.c -Wall
[bushi@rose net]$ 
[bushi@rose net]$ AA=yes ./disabled 'AA'
enabled
[bushi@rose net]$ AA=yes ./disabled '!AA'
disabled
[bushi@rose net]$ AA=no ./disabled '!AA'
enabled
[bushi@rose net]$ AA=no ./disabled 'AA'
disabled
[bushi@rose net]$ 

OTL

sunnyncom의 이미지

감사합니다... 친절한 설명까지.... ㅎㅎ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.