给我做一个三明治


21

XKCD:三明治

挑战:编写一个makefile,这将导致以下行为:

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

规则:

  1. 应该在Linux机器上工作,该机器不是root用户,但允许使用sudo
  2. 一定不要说Okay任何更短的make命令(例如sudo make sandwich)。
  3. 第二个命令应该由于起作用sudo,而不是因为它是第二个调用。

指导原则:

  1. 保持简短(毕竟,这是Code Golf网站)。
  2. 如果它真的能做一个三明治,那就太好了。
  3. 尝试巧妙地隐藏为什么sudo有所作为。

获胜者将由投票决定。



不幸的是,@ ardnew我特别要求编写一个makefile,我认为该文件会使基于patching的解决方案失效make
ugoren

完全同意,@ ugoren。并不意味着该评论会消除挑战或提出解决方案
ardnew

Answers:


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

啊,你是对的。此版本应更好地遵守规则。
面包箱

1
您当然拥有最合适的名称@breadbox
ardnew

9

一种相当紧凑的解决方案,它忽略了准则2(127个字符,包括一些不必要的空格)。我遵循面包箱的清理习惯。不要将任何其他文件与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的要求吗?或者是模糊的三明治形状计数吗?一开始我就以回文主题为主题,但是我只能找到许多使线对称而不求助于la脚的方法real code # ecod laer。我没有认真对待准则1,美学是第一位的。

请记住,这是一个makefile;以开头的3个连续行ifrmecho以制表符开头。其他缩进线以空格开头。

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无法打印?


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

我非常确定我可以做更多的事情-例如使其响应其他输入命令。我将不得不进行根交换机的混淆处理和实际的三明治制作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.