Ein Programm, das sich selbst löscht


22

Wenn eine kompilierte Sprache verwendet wird, muss das Programm die kompilierte ausführbare Datei löschen (die Quelldatei muss jedoch nicht gelöscht werden). Wenn eine interpretierte Sprache verwendet wird, muss das Programm die Quelldatei löschen.

Mein Eröffnungsgebot:

Python (29 Zeichen)

import os;os.remove(__file__)

Bearbeiten: Um Lösungen wie rm -rf / zu verhindern , darf das Programm nur die ausführbare Datei oder die Quelldatei löschen.

html,body{margin:0;padding:0;height:100%;overflow:hidden}
 <iframe src="https://xmikee1.github.io/ppcg-leaderboard/?id=19355" width="100%" height="100%" style="border:none;">Oops, your browser is too old to view this content! Please upgrade to a newer version of your browser that supports HTML5.</iframe>



2
@ JanDvorak Diese Frage war strenger und erforderte eine EXE-Datei. Das ist lockerer.
EMBLEM

Hmm ... was ist, wenn ich dafür stimme, in die entgegengesetzte Richtung zu schließen?
John Dvorak

3
Code-Golf, kein Beliebtheitswettbewerb ? Aww.
Justin

10
@Quincunx Ich glaube nicht an Beliebtheitswettbewerbe. Realer Code wird nicht zuerst auf seine Eleganz überprüft, sondern auf seine Korrektheit.
EMBLEM

Antworten:


21

Bash-Skript (7 Zeichen, 7 Bytes)

rm "$0"

1
Funktioniert nicht, wenn der Skriptdateiname Leerzeichen enthält.
user80551

Gutes Auge! Ich habe das Skript aktualisiert, um mit Dateien mit Leerzeichen zu arbeiten. Fügt nur zwei weitere Zeichen hinzu. Vielen Dank!
anthony.c

Funktioniert dies, wenn der Dateiname doppelte Anführungszeichen enthält?
John Dvorak

1
@ JanDvorak: Ja. Durch die Ausführung , die zum Beispiel wäre ./the\"program, ./'the"program', './tha"program'. Alles funktioniert wie vorgesehen. (Anführungszeichen müssen beim Abruf maskiert oder in einfache Anführungszeichen eingeschlossen werden.) Funktioniert auch bei Dateien mit Namen mit Zeilenvorschub usw.
Runium

1
@ StéphaneGourichon Wahrscheinlich, weil er rm "$0"in der Bash- Shell anstatt in einem Batch- Skript ausgeführt wird . Sie sollten den Header folgendermaßen bearbeiten:# Bash script, 7 bytes
MD XF

15

Unix? (9):

#!/bin/rm

Ein Klassiker. Verwendet rmals Interpreter für die sofortige Selbstlöschung. Nicht die allerkürzeste.


5
Oder wenn Sie schummeln wollen: ein 0-Byte- rmProgramm.
nyuszika7h

1
Die #!Linie wird nicht in der Punktzahl gezählt.
Pavel

@Phoenix: Es ist ungewöhnlich für die Sprache, die Sie verwenden. Nur vollständig standardisierte #!Zeilen, die nur den Namen des Standardinterpreters der Sprache enthalten, werden als Null gewertet. Dies ist eine sehr ungewöhnliche #!Linie, was Bash betrifft. (Nicht, dass dies tatsächlich in Bash funktioniert, obwohl es andere Sprachen gibt, in denen es funktioniert.)

1
Dies ist eigentlich kein Bash-Programm (wenn Sie es explizit mit ausführen bash, wird nichts gelöscht). Es ist eine UNIX / Linux-Programmdatei. (Es funktioniert auch in Perl, das die Verarbeitung von #!Zeilen unter UNIX / Linux emuliert , sodass Shellscripts auf Plattformen ausgeführt werden können, auf denen dies nicht möglich ist.)

@Pavel Hmm ... 0 Bytes?
11.

10

Batch - 6 Bytes

Del %0

Ziemlich einfach. Hinweis: Funktioniert auch, wenn der Name Leerzeichen enthält.


Nur wenn der Dateiname keine Leerzeichen enthält.
Isiah Meadows

@impinball, Entschuldigung?
Unclemeat

Ich weise nur auf einen kleinen Fehler hin. Wenn Sie DOS angeben, ist dies nicht der Fall, aber es kann unter Windows (z. B. in Programme) leicht zu Problemen kommen. Keine Entschuldigung nötig.
Isiah Meadows

Mein Schlimmes ... es ist okay. Ich habe mich nicht daran erinnert, dass in diesem Fall keine Anführungszeichen erforderlich sind, da sie automatisch in diese eingeschlossen werden.
Isiah Meadows

Alles gut. Durch Hinzufügen einer Tilde werden umgebende Anführungszeichen entfernt. %~0.
Unclemeat

9

Ruby, 14 Zeichen

File.delete $0

$0 ist eine spezielle globale Variable, die den Namen des aktuell ausgeführten Skripts enthält.


Ich bin mir ziemlich sicher, dass Sie den Raum fallen lassen können.
Darren Stone

Aus diesem Grund habe ich meine Version der Frage viel strenger gestaltet. Interpretierte Sprachen können das problemlos. Die Idee ist, dass eine native Anwendung den Teppich nicht einfach unter sich herausziehen kann
Cruncher

6

BASIC-80 / BASICA / GW-BASIC / IBM BASIC / Commodore 64 BASIC / Vintage BASIC / Commodore LCD BASIC / Atari BASIC *

5 Bytes

1 NEW

Das ist so einfach wie es nur geht. NEWErstellt ein neues Programm. Wenn Sie dieses also an einer beliebigen Stelle in Ihrem Programm platzieren, wird es gelöscht.

Proof of Concept auf IBM BASIC ( NEWaus Gründen der Übersichtlichkeit Zeile 40 einfügen):

* Ja, ich habe jede alte BASIC-Version aufgelistet, in der ich das getestet habe (oder die ich so ziemlich immer benutzt habe)


2
+1, Das hat etwas Poetisches. Existenziell sogar.
Wossname

5

PHP, 17 Zeichen

unlink(__FILE__);

6
Ich bin mir nicht sicher, warum jemand dies ablehnen würde. es ist vollkommen gültig. Möglicherweise möchten Sie jedoch ein offenes Tag einfügen<?unlink(__FILE__);
primo

4
Dieses PHP-Programm druckt unlink(__FILE__);. Die Datei wird nicht gelöscht.
Richtig

1
@rightfold es funktioniert wie beschrieben, wenn Sie einen Eröffnungs-Tag einfügen, den ich vermutlich hinzugefügt hätte
Darren H


3

Perl 5 (8 Zeichen)

unlink$0

$0ist der Skriptname und unlinkentfernt ihn. Normalerweise fügen Sie zur besseren Lesbarkeit mindestens ein Leerzeichen dazwischen ein.



3

k (8)

~-1!.z.f

Oder das q-Äquivalent für 14:

hdel hsym .z.f

3

Python, 18

open(__file__,'w')

Öffnet sich im Nur-Schreib-Modus und löscht sich.


9
Dies schneidet die Datei ab. Es wird nicht gelöscht.
Richtig




1

Vitsy + Bash, 8 Bytes

iG' mr',

iG       Get the name of the use declaration at the top item (-1) (returns the current one)
  ' mr'  Concatenate "rm " to the front of it.
       , Execute via shell.


1

Lua, 17 Bytes

os.remove(arg[0])

Dies funktioniert eigentlich nur, wenn Sie das Programm ausführen, indem Sie den vollständigen Dateipfad eingeben, das heißt , wenn Sie einen Dateinamen von und ein aktuelles Arbeitsverzeichnis von annehmen,
lua ~/Scripts/removeself.luawürde dies funktionieren, aber lua removeself.luanicht .removeself.lua~/Scripts

Soweit ich weiß, gibt es keine Möglichkeit, den tatsächlichen Dateipfad eines Skripts zu ermitteln, sondern nur die Argumente, die an dieses Skript übergeben wurden. Ich weiß debug.getinfo(1).source, aber in meinem Test dieses Spiel genau die gleichen Ergebnisse wie arg[0]. Wenn jemand eine Möglichkeit kennt, den Dateipfad zu finden, lass es mich wissen.




1

tcl, 18

file delete $argv0

Demo - ACHTUNG: Es ist nur eine einmalige Demo! Nur das erste Mal wird es lauffähig sein. Bitte reservieren Sie es auf dem Originalposter der Frage. Zum Ausprobieren: Drücken Sie die ExecuteTaste. Der grüne Bereich meldet keinen Fehler. Danach führen alle nachfolgenden Klicks auf die ExecuteSchaltfläche zu einem not foundFehler!


1

C 32 Bytes

main(c,v)char**v;{remove(v[0]);}

1
Fehlende }s sind in C erlaubt? Wow!
CalculatorFeline

Nein, nur ein Tippfehler! Meine Zeichenanzahl beinhaltete das Schließen, }aber ich habe das Snippet offensichtlich falsch kopiert / eingefügt. Vielen Dank für den Hinweis!
Josh

Nun, da der anonyme Downvoter keine Lust hat, einen Kommentar zu hinterlassen oder seine Stimme zurückzuziehen, habe ich meine Antwort gelöscht, die ich auf deiner basiert habe. Sie können bis zu 29 Bytes Golf spielen:main(c,v)int**v;{remove(*v);}
MD XF

@MDXF Ich bin nicht sicher, ob der Wechsel char**zu int**technisch gültig ist. Ich mache mir Sorgen um mögliche Ausrichtungsprobleme.
Josh

1
@ Josh Nun; es funktioniert ... also verstehe ich nicht warum nicht. Beim Codegolf dreht sich alles um schreckliche Methoden, die technisch nicht gültig sind.
MD XF

1

JavaScript (ES6), 13 Byte

f=_=>delete f

Versuch es

Protokolliert die Quelle von f, ruft auf f(die gelöscht wird f), versucht erneut zu protokollieren f, gibt jedoch einen Fehler aus, da sie fjetzt undefiniert ist.

f=_=>delete f
console.log(f)
f()
console.log(f)



0

Julia - 25 Bytes

Schreiben Sie dies in eine Datei, fügen Sie die Datei dann hinzu include("<filename here>")und führen Sie Folgendes aus f():

f()=rm(functionloc(f)[1])

Dies ist offensichtlich eine Funktion. Ich bin nicht sicher, wie man den Dateinamen einer Datei ermitteln soll, die direkt ausgeführt wird (als Include-Anweisung ohne darin enthaltene Funktionsdefinition).


0

C ++, 137 Bytes.

Funktioniert die meiste Zeit unter Windows

#include <stdlib.h> 
#include <string>
int main(int, char*v[]){char c[99];sprintf(c,"start cmd /C del \"%s\"/Q", *v);return system(c);}

C 90 Bytes

void main(int n,char**v){char c[99];sprintf(c,"start cmd /C del \"%s\"/Q", *v);system(c);} 

Meistens?
Addison Crump

1
Sie könnten eine Menge Bytes einsparen, indem Sie die nicht verwendeten #include <string>, überflüssigen Leerzeichen entfernen und dieses C erstellen, mit dem Sie das intund entfernen können return. Darüber hinaus müssen Sie #include <stdio.h>diese Funktion ausführen, da dort sprintfdeklariert ist.
Mego

0

MATLAB, 36 Bytes

delete([mfilename('fullpath'),'.m'])

Speichern Sie den obigen Code als M-Datei gemäß den Dateinamenrichtlinien von Matlab.


0

VBA, 69 67 Bytes

Subroutine, die keine Eingabe nimmt und sich selbst löscht.

Erfordert, dass der unten stehende Code die erste Zeile im aktiven Codebereich ist und dass VBA vertrauenswürdigen Zugriff auf das VBE-Projektmodell hat.

Sub a:Application.VBE.CodePanes(1).CodeModule.DeleteLines 1:End Sub

-2 Bytes zum Ersetzen ActiveCodePanedurchCodePane(1)


0

T-SQL, 28 Bytes

CREATE PROC d AS DROP PROC d

Es löscht / entfernt nur die Prozedur und den Code, wenn es sich selbst ausführt. Verwendung:

EXECUTE d

0

shortC , 10 Bytes

Aremove(*@

Wie es funktioniert:

A           main function
 remove(    delete file specified in next string
        *@  program name

Äquivalentes C-Programm:

int main(int argc, char **argv){remove(*argv);}

0

8086/8088 Maschinencode, 1 Byte

aa    stosb

Annahmen:

  • Die Register CS, IP, ES, DI und AL sind alle anfänglich 0.
  • Dieser Code befindet sich unter der Adresse 0.

Das stosb Befehl speichert das Byte im AL-Register an der Speicherstelle, auf die ES und DI zeigen, und erhöht oder erniedrigt dann DI. In diesem Fall speichert es das Byte 0 an der Speicheradresse 0, die sich zufällig dort befindet, wo sich der Befehl selbst befindet.

Zugegeben, dieses Programm löscht keine Datei oder ähnliches. Wenn Sie es jedoch schaffen, einen 8086-Prozessor in den Griff zu bekommen, dieses Programm in den Speicher zu bekommen und auszuführen, überschreibt es sich in der Tat von selbst.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.