ทำให้ฉันเป็นแซนวิช


21

XKCD: แซนด์วิช

ถาม: เขียนไฟล์ซึ่งจะนำไปสู่พฤติกรรมนี้:

% 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. ทำให้สั้น (หลังจากทั้งหมดเป็นเว็บไซต์ Code Golf)
  2. มันคงจะดีถ้ามันทำแซนด์วิชจริงๆ
  3. พยายามซ่อนอย่างชาญฉลาดว่าทำไมsudoสร้างความแตกต่าง

ผู้ชนะจะได้รับการตัดสินด้วยคะแนนเสียง



@ardnew โชคไม่ดีที่ฉันเฉพาะขอให้เขียน Makefile makeซึ่งผมคิดว่าการแก้ปัญหาการเลิกขึ้นอยู่กับปะ
ugoren

เห็นด้วยอย่างยิ่ง @ugoren ไม่ได้หมายความว่าการแสดงความคิดเห็นนั้นจะยกเลิกการท้าทายหรือแนะนำวิธีแก้ปัญหา
ardnew

คำตอบ:


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 - หรือนับเป็นรูปแซนด์วิชอย่างคลุมเครือ ผมไปอยู่กับชนิดของรูปแบบประโยคที่จุดเริ่มต้น แต่ฉันเท่านั้นที่สามารถหาหลายวิธีเพื่อทำให้เส้นสมมาตรโดยไม่ต้อง resorting 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ไม่ให้พิมพ์อย่างไร


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.