샌드위치 만들기 make me a

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차이를 만드는 이유를 영리하게 숨기십시오 .

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



답변

알았어. 반드시 가이드 라인 # 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를 무시하는 상당히 컴팩트 한 솔루션 (일부 불필요한 공백을 포함하여 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차이가 발생합니다.


답변

이 솔루션은 가이드 라인 # 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


답변

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

.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

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