サンドイッチを作る


21

XKCD:サンドイッチ

課題:この動作につながるメイクファイルを作成します。

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

ルール:

  1. ユーザーはrootではなく、の使用を許可されているLinuxマシンで動作するはずsudoです。
  2. Okay短いmakeコマンド(例sudo make sandwich)に言ってはいけません。
  3. 2番目のコマンドはsudo、2番目の呼び出しではなく、のために機能するはずです。

ガイドライン:

  1. 短くしてください(結局、これはCode Golfサイトです)。
  2. 実際にサンドイッチを作ってくれるといいですね。
  3. なぜsudo違いが生じるのかを巧みに隠そうとします。

勝者は投票によって決定されます。



@ardnew、残念ながら、私は具体的にメイクファイルを書くことを要求しましたmake
ウゴレン

@ugoren、完全に同意します。そのコメントが課題を却下したり、解決策を提案したりすることを意味するものではあり
ませんでした

回答:


12

さて、噛みます。これは必ずしもガイドライン#3に準拠しているわけではありませんが、他の2つのガイドラインについては公正な仕事をしています。また、優れたサンドイッチメーカーがそうであるように、自動的にクリーンアップします。

.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です。
ウゴレン

&& test -e ./a
luserはドローグ

ああ、あなたは正しい。このバージョンは、ルールを順守するのにより良い仕事をするはずです。
ブレッドボックス

1
確かに最も適切な名前@breadboxがあります
-ardnew

9

ガイドライン#2(127文字、不要な空白を含む)を無視するかなりコンパクトなソリューション。私は自分の後にクリーンアップするブレッドボックスの慣習に従います。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を扱う方法が好きです。1回押すだけでShift違いが生じます。


3

この解決策はガイドライン#2に準拠していません。または、漠然とサンドイッチの形をしていますか?冒頭で一種の回文のテーマに取り組みましたが、ラメに頼らずに線を対称にする方法はたくさんありましたreal code # ecod laer。私はガイドライン#1をあまり真剣に受け止めていませんでした、美学が最初に来ます。

メイクファイルであることを忘れないでください。始まる3本の連続ラインifrmおよび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に関しては、これは巧妙に隠されているわけではなく、少し奇妙に見えます。いくつかのヒント:

2つの異なるテストがあります。1つはを検索しSUDO_USER、もう1つはid -u0を印刷するかどうかをテストします。ルートが印刷されない理由What?がわかりますか?あなたはどのように原因の欠如を見ていますかSUDO_USEROkayように印刷されないのか?


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.