Bana bir sandviç yap


21

XKCD: Sandviç

Zorluk: Bu davranışa yol açacak bir makefile yazın:

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

Kurallar:

  1. Kullanıcının root olmadığı ancak kullanmasına izin verilen bir Linux makinesinde çalışmalıdır sudo.
  2. OkayHerhangi bir kısa make komutunu söylememelisiniz (örn. sudo make sandwich).
  3. İkinci komut sudo, ikinci çağrı olduğu için değil, çalışması gerekir .

Kuralları:

  1. Kısa tutun (sonuçta bu bir Code Golf sitesidir).
  2. Bir sandviç yaparsa iyi olur.
  3. Neden sudobir fark yarattığını zekice gizlemeye çalışın .

Kazanan oy ile karar verilecek.



@ardnew, ne yazık ki, özellikle yamalamaya dayanan çözümleri geçersiz kılan bir makefile yazmayı özellikle istedim make.
ugoren

Tamamen katılıyorum, @ugoren. bu yorum için mücadeleyi reddetmek ya da bir çözüm önermek
istemedi

Yanıtlar:


12

Tamam, ısırırım. Bu mutlaka 3. kılavuza uymuyor, ancak diğer iki kılavuzda adil bir iş yapıyor. Aynı zamanda iyi bir sandviç yapıcısının yapması gerektiği gibi kendisi de temizlenir.

.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

(İlk gönderimden daha az buggy ve umarım biraz daha sıkıcı olur.)


Kural 2'yi ihlal ediyor gibi görünüyor - sudo make me sandwich.
ugoren

&& test -e ./a
luser droog

Argh, haklısın. Bu sürüm kurallara uyarak daha iyi bir iş çıkarmalıdır.
breadbox

1
kesinlikle en uygun isme sahipsin, @breadbox
ardnew

9

Kılavuz 2'yi görmezden gelen oldukça kompakt bir çözüm (bazı gereksiz boşluklar dahil 127 karakter). Breadbox'ın temizlik işlerini kendim takip ediyorum. Başka bir dosyayı makefile ile aynı dizine koymayın! Ayrıca, makefile çağrılması gerektiğini unutmayın Makefile, diğer isimler çalışmayacak.

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

Kullanımı:

$ 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

Bunun 3. kılavuzla ilgilenme şeklini seviyorum. Sadece bir basış Shiftfark yaratır.


3

Bu çözüm # 2 kılavuzuna uymuyor mu - yoksa belli belirsiz sandviç şeklinde sayılıyor mu? Başlangıçta bir çeşit palindrome temasına girdim, ancak çizgileri topallamaya başvurmadan simetrik yapmak için pek çok yol bulabildim real code # ecod laer. Rehber 1'i çok ciddiye almadım, estetik önce gelir.

Bir makefile olduğunu unutmayın; 3 ardışık çizgiler ile başlayan if, rmve echobir sekme ile başlar. Diğer girintili çizgiler boşluklarla başlar.

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

Kullanım (komutlar herhangi bir sırayla verilebilir):

$ 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

İlke # 3'e gelince, bu akıllıca gizli değil, sadece biraz garip. Bazı ipuçları:

İki farklı testler vardır: için tek arama SUDO_USERve biri deney olmadığını id -ubaskılar 0. neden görebilirsiniz Do What?edilir değil root için basılmış? SUDO_USERSebeplerin eksikliğinin nasıl Okayyazdırılmayacağını görüyor musunuz ?


2

İşte farklı ve daha basit bir teknik kullanan ilk adım:

.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

Bununla daha fazlasını yapabileceğimden eminim - örneğin diğer giriş komutlarına cevap vermesini sağlayın. Kök şalter şaşırtma ve gerçek sandviç yapımı üzerinde çalışmak zorunda kalacağım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.