샌드위치 만들기


21

XKCD : 샌드위치

도전 과제 : makefile을 작성하면 다음과 같은 동작이 발생합니다.

% make me a sandwich
What? Make it yourself
% sudo make me a sandwich
Okay

규칙 :

  1. 사용자가 루트는 아니지만 사용할 수있는 Linux 시스템에서 작동해야합니다 sudo.
  2. Okay더 짧은 make 명령 (예 :)을 말해서 는 안됩니다 sudo make sandwich.
  3. 두 번째 명령이 아니기 때문에 두 번째 명령이 작동해야합니다 sudo.

지침 :

  1. 짧게 유지하십시오 (결국 코드 골프장입니다).
  2. 실제로 샌드위치를 ​​만들면 좋을 것입니다.
  3. sudo차이를 만드는 이유를 영리하게 숨기십시오 .

우승자는 투표에 의해 결정됩니다.



불행히도 @ardnew는 makefile 작성을 요청했는데 패치를 기반으로 솔루션을 무효화한다고 생각 make합니다.
ugoren

@ugoren에 전적으로 동의합니다. 그 의견이 도전을 기각하거나 해결책을 제시한다는 의미는
아니었다

답변:


12

알았어. 반드시 가이드 라인 # 3을 준수 할 필요는 없지만 다른 두 가이드 라인에서는 공정하게 작동합니다. 또한 좋은 샌드위치 메이커가 해야하는 것처럼 자체적으로 정리됩니다.

.SILENT:

%:%.c
        $(CC) -o $@ $^ && rm -f $^

default:
        echo 'The makings for a sandwich are here.'

a.c:
        echo '#include <stdio.h>' > a.c
        echo 'int main() {' >> a.c
        echo '  char *txt[] = { "What? Make it yourself.", "Okay." };' >> a.c
        echo '  int n = 0;' >> a.c
        echo '  while (getchar() != EOF) n ^= 1;' >> a.c
        echo '  puts(txt[n]); return 0; }' >> a.c

me.c:
        echo '#include <stdio.h>' > me.c
        echo '#include <unistd.h>' >> me.c
        echo 'int main() {' >> me.c
        echo '  char *txt[] = { "/dev/null", "sandwich" };' >> me.c
        echo '  puts(txt[!getuid()]); return 0; }' >> me.c

sandwich:
        ./me | ./a | tee `./me`
        rm -f me a

clean:
        rm -f sandwich

(내 초기 제출보다 버그가 적고 약간 지루하지 않습니다.)


규칙 # 2-을 위반 한 것 같습니다 sudo make me sandwich.
ugoren

&& test -e ./a
luser droog

아아, 네 말이 맞아 이 버전은 규칙을보다 잘 준수해야합니다.
breadbox

1
당신은 확실히 가장 적절한 이름을 가지고 있습니다 : @breadbox
ardnew

9

가이드 라인 # 2를 무시하는 상당히 컴팩트 한 솔루션 (일부 불필요한 공백을 포함하여 127 자). 나는 자신을 따라가는 breadbox의 청소 방법 을 따릅니다 . makefile과 같은 디렉토리에 다른 파일을 넣지 마십시오! 또한 makefile을 호출해야하며 Makefile다른 이름은 작동하지 않습니다.

me: ; echo echo Okay >$@
a: ; chmod u=x me
sandwich: ; ./me 2>/dev/null || echo 'What? Make it yourself'; rm -f [!M]*
.SILENT:

용법:

$ make me a sandwich
What? Make it yourself
$ sudo make me a sandwich
Okay
$ sudo make me sandwich  
What? Make it yourself
$ sudo make a sandwich
chmod: cannot access `me': No such file or directory
make: *** [a] Error 1
$ sudo make sandwich  
What? Make it yourself

나는 이것이 지침 # 3을 다루는 방식을 좋아한다. 한 번만 누르면 Shift차이가 발생합니다.


3

이 솔루션은 가이드 라인 # 2를 준수하지 않거나 모호한 샌드위치 모양입니까? 나는 처음에 일종의 회문 테마를 진행했지만, 절름발이에 의존하지 않고 선을 대칭으로 만드는 많은 방법을 찾을 수있었습니다 real code # ecod laer. 나는 가이드 라인 # 1을 매우 진지하게 고려하지 않았으며, 미학이 먼저입니다.

그것이 makefile이라는 것을 기억하십시오. 3 개 연속 라인으로 시작 if, rm그리고 echo탭으로 시작합니다. 들여 쓰기 된 다른 줄은 공백으로 시작합니다.

me : mr ; env | grep -q DO_US || rm -- mr || SU_OD q- perg | vne ; rm : em
                            .SILENT:##:TNELIS.
                              . = a.  .a = .
$(.:.=):;:>$@
sandwich:
    if expr>/dev/null $$(id -u); then echo 'What? Make it yourself'; fi
    rm f- a me mr 2>/dev/null
    echo Okay
mr : ; true : ; touch me : em f- mr || rm -f me : em hcuot ; : eurt ; : rm

사용법 (명령은 임의 순서로 발행 할 수 있음) :

$ sudo make me a sandwich     
Okay
$ sudo make me sandwich  
make: *** [sandwich] Error 1
$ sudo make a sandwich 
make: *** [sandwich] Error 1
$ sudo make sandwich  
make: *** [sandwich] Error 1
$ make me a sandwich
What? Make it yourself
make: *** [sandwich] Error 1

지침 # 3에 관해서는, 이것은 영리하게 숨겨져 있지 않고 약간 이상하게도 숨겨져 있습니다. 몇 가지 힌트 :

두 가지 다른 테스트가 있습니다. 하나는을 검색 SUDO_USER하고 다른 하나 id -u는 0을 인쇄 하는지 여부에 대한 테스트입니다. 루트로 인쇄 되지 않은 이유 What?는 무엇입니까? 원인 부족 이 인쇄되지 않는 방법을 알고 있습니까?SUDO_USEROkay


2

다음은 다른 간단한 기술을 사용하는 첫 번째 방법입니다.

.SILENT:

reset_command:
    @rm -f command

me a sandwich: reset_command
    @echo $@ >> command
    -@make `cat command | tr "\n" "_"` 2>/dev/null

me_a_sandwich_: reset_command
    @if [ `whoami` == "root" ]; then echo "Okay"; else echo "What? Make it yourself."; fi

나는 이것으로 할 수있는 일이 더 있다고 확신합니다. 예를 들어 다른 입력 명령에 응답하십시오. 루트 스위치 난독 화와 실제 샌드위치 만들기 작업을해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.