도전 과제 : makefile을 작성하면 다음과 같은 동작이 발생합니다.
% make me a sandwich
What? Make it yourself
% sudo make me a sandwich
Okay
규칙 :
- 사용자가 루트는 아니지만 사용할 수있는 Linux 시스템에서 작동해야합니다
sudo
. Okay
더 짧은 make 명령 (예 :)을 말해서 는 안됩니다sudo make sandwich
.- 두 번째 명령이 아니기 때문에 두 번째 명령이 작동해야합니다
sudo
.
지침 :
- 짧게 유지하십시오 (결국 코드 골프장입니다).
- 실제로 샌드위치를 만들면 좋을 것입니다.
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_USER
Okay
답변
다음은 다른 간단한 기술을 사용하는 첫 번째 방법입니다.
.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
나는 이것으로 할 수있는 일이 더 있다고 확신합니다. 예를 들어 다른 입력 명령에 응답하십시오. 루트 스위치 난독 화와 실제 샌드위치 만들기 작업을해야합니다.