Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

The mission is to implement a cat-like program (copy all stdin to stdout) in less than 100 bytes of code.


  • You may only use standard libraries
  • Indentation must be either two spaces or a single tab (in languages which require indentation)
  • Scripts must use shebangs
  • The result of cat anything.txt | ./yourprogram | diff anything.txt - should be nothing and should not be an infinite loop

Go example (84 bytes)

package main
import (
func main() {

C++ example (78 bytes)

using namespace std;
int main() {
  cout << cin.rdbuf();

Ruby example (44 bytes)

#!/usr/bin/env ruby
$stdout << $stdin.read

Shortest code (by bytes) wins.

share|improve this question
This indentation thing is nonsense –  edc65 Jun 15 '14 at 12:49
@ProgramFOX Stoning the Rosetta. –  Seeq Jun 15 '14 at 12:53
The indentation rule doesn't make sense, the shebang one makes even less, because shebangs can be platform-specific, especially in the case of Python. –  nyuszika7h Jun 15 '14 at 14:50
until end of June 2914… Woaah… –  Qeole Jun 15 '14 at 18:03
Also, person with most implementation? What? –  nyuszika7h Jun 15 '14 at 18:50

32 Answers 32

GolfScript, 0 characters / bytes

This could technically be considered invalid since GolfScript will append a \n, but that can be fixed with :n; (3 bytes).

share|improve this answer
Haha, +1. Explanation for people who don't speak golfscript: stdin is read to the stack when the program starts and the stack is outputted when it ends. –  Seeq Jun 15 '14 at 12:47
Nice idea, but invalid. GolfScript will append a linefeed to the input. –  Dennis Jun 15 '14 at 13:55
+1 for unicorn waffles. –  Martin Büttner Jun 15 '14 at 13:55
@Dennis That could be fixed in 3 bytes: :n; (edited) –  Doorknob Jun 15 '14 at 14:11
I would say then that the zero-char solution is, unfortunately, invalid, and therefore the score is a solid 3. +1 nonetheless! –  Jwosty Jun 16 '14 at 4:56

sed - 0 bytes

No command needed to cat a file with sed: all lines of input are printed without modification, so

sed ''

will act like cat for standard input, and

sed '' /etc/fstab

will print content of file.

share|improve this answer
"sed n" works for me and is one byte shorter. –  Glenn Randers-Pehrson Aug 5 '14 at 18:04
@GlennRanders-Pehrson Yes, thank you. I didn't count the quotes as part of the sed script (I considered an empty script, something similar to sed -f /dev/null input). If we are to count chars on the line, your proposal saves a byte indeed. –  Qeole Aug 5 '14 at 20:54

Haskell - 17 bytes

main=interact id

id is the identity function and from the documentation :

The interact function takes a function of type String->String as its argument. The entire input from the standard input device is passed to this function as its argument, and the resulting string is output on the standard output device.

share|improve this answer

ΒrainFuck (5 bytes)



,  Read first byte of input and place on stack
[  While top byte is not 0...
 . Print top byte from stack as ASCII and remove
 , Read next byte of input and place on stack
]  ...loop
share|improve this answer
one of those few tasks where BF is shorter than most other things... –  professorfish Jun 20 '14 at 19:54
This is less than 2 bytes (each command is 3 bits... totaling 15 bits). –  Timtech Jun 23 '14 at 23:01
It is not 3 bits when stored in ASCII format, and I wrote it as ASCII. –  kitcar2000 Jun 24 '14 at 14:35
This will fail on files with a null in them though.. –  Claudiu Sep 10 '14 at 20:46

C 43

share|improve this answer
You can use ~(c=getchar()) instead of (c=getchar())>=0 to save 2 characters. –  nyuszika7h Jun 15 '14 at 13:59
@nyuszika7h: EOF is typically -1, but this is not guaranteed by the standard. The standard only defines about EOF in section 7.19.1: EOF which expands to an integer constant expression, with type int and a negative value, that is returned by several functions to indicate end-of-file, that is, no more input from a stream; –  edc65 Jun 15 '14 at 16:11
main(){for(;putchar(getchar())<127;);} what's with that? (apparently putchar's return value is casted to int so EOF becomes 255) –  bebe Jun 18 '14 at 17:54
@bebe yes it's pity. putchar get an int but truncates it to 8 bits. (It's in the spec) –  edc65 Jun 18 '14 at 18:35
@edc65 VC++ error C2065: 'c':undeclared identifier. Yes, sorry my comment about putchar was incorrect. –  bacchusbeale Jun 23 '14 at 19:43

x86_64 NASM Assembly for Linux - 125 / 100

r:mov ax,0
mov di,0
mov rsi,c
mov dx,1
cmp ax,0
je e
mov di,1
jg r
e:mov ax,60
c:resw 1

I couldn't get it to fit in 100 bytes, but it is assembly. Eight bytes could be saved at the cost of changing the return status to 1 instead of 0:

r:mov ax,0
mov di,0
mov rsi,c
mov dx,1
cmp ax,0
mov di,1
jg s
mov ax,60
jg r
c:resw 1

Now, if you really want 100 bytes, here is one in exactly 100 bytes. The problem is that it doesn't exit correctly, it just segfaults:

r:mov ax,0
mov di,0
mov rsi,c
mov dx,1
cmp ax,0
mov di,1
jg r
c:resw 1

The instructions say to only use standard libraries; is there extra credit for using no libraries at all?

share|improve this answer

Linux/Unix tools, 16 bytes

grep $

Other tools that work when called by bash/sh are

tr . .

and (15 bytes)

sed n

EDIT: Changed title from "bash/sh" to "Linux/Unix tools" because although the tools can be called by bash or sh they aren't actually part of bash or sh.

share|improve this answer
Copies the indentation? –  Seeq Jun 15 '14 at 12:54
@TheRare yes. It copies "all stdin to the stdout," as required. I guess that the 2-space indentation requirement refers to indentation of the code. –  Glenn Randers-Pehrson Jun 15 '14 at 12:59
Yes, yes it does. –  Seeq Jun 15 '14 at 13:01
shebangs don't count towards your score (and why are they #!/bin/sh? that isn't bash) –  professorfish Jun 18 '14 at 16:35
@professorish /bin/sh is Bash on my platform (Ubuntu 14.04) Perhaps I should have said Ubuntu and RedHat Fedora in my answer instead of "many systems" (will edit accordingly). In the example for ruby shown in the question, the shebang is counted among the 44 bytes. –  Glenn Randers-Pehrson Jun 18 '14 at 16:47

Node.js 55

#!/usr/bin/env node
share|improve this answer
Could shorten by assigning p=process first to avoid repetition. Just plain #!env node works unless you've got a non-standard filesystem layout or funky $PATH stuff going on. Alternatively, drop the shebang line (so the default sh is used) and do node -e '<program>' because that's the same (6) extra number of characters and stays system-general. (If you want to join the dark side, rename your node binary to n.) Aaand drop the semicolon. –  Anko Sep 15 '14 at 9:41

Perl (1)

0+1 for the -p parameter

If really the shebang counts, invoke it like this: perl -p nul on M$ or perl -p /dev/null on *nix so no shebang is involved :P

D:\>copy con cat.pl
#!perl -p
        1 file(s) copied.

D:\>type cat.pl
#!perl -p

D:\>type cat.pl | cat.pl
#!perl -p

share|improve this answer

AWK - ???

The complete program in awk has only 1 char:


Unluckily the shebang stuff lets kinda explode it's length :(

#!/usr/bin/awk -f

May I copy awk into the filesystem root? >;-)

As oneliner it is shorter:

$ awk 1 </etc/hostname 

I'm not sure what counts and what not...

share|improve this answer
In my experience, code in codegolf doesn't use shebangs, it is intended to be directly executed by the interpreter (awk in this case). –  Ramchandra Apte Jun 15 '14 at 13:42
Thinking about stdout = g(f(stdin))... <input tac|tac >output fails if the last input line has no linefeed. I like <input rev|rev >output. So far for f = g. What comes into the game for f != g? tr and it's inverse? sed and backwards? Smells not really promising... –  yeti Jun 17 '14 at 14:59
A flash of enlightenment hit me: tee ftw!!! :) –  yeti Jun 18 '14 at 14:35
At least in OpenBSD, printf 'full\0string' | awk 1 outputs 'full\n', so it is not perfect. I wonder if gawk or mawk does better? –  kernigh Jun 20 '14 at 21:01

Bash, 3

If you need a shebang, #!/bin/sh or #!/bin/bash is probably fine.

Had to be done. Hopelessly uncreative.


Slightly more interesting:


Normally, tee FILENAME sends its input both to the file and to standard output. Without an argument, it seems to behave like cat.

Bash, 2

...if you don't mind the status message at the end and the fact that the output only comes after EOF on standard input!


Removing the status message costs 4 chars for a total of 6 chars:

dd 2>a

The message is sent to the file a instead of standard output.

If you dispose of the message entirely, the total length is 14 7:

dd 2>&-

Bash/SHELF, 1

For the shebang, try

. shelf.sh

where shelf.sh is the location of your SHELF file.

SHELF is my PYG-like golfing library for Bash.


D just aliases to cat. Also uncreative.

And the alias for tee is...

share|improve this answer
2>&- is shorter than 2>/dev/null. –  nyuszika7h Jun 26 '14 at 11:35

Python 2.x - 56 or 61 bytes

Input limited to 10^9 bytes.

from os import*

Or for infinite input (61 bytes):

from sys import*

Not much to say, is there?

share|improve this answer
This isn't cat because it adds a linefeed or whatever your system uses (cr+lf?) to the output. –  yeti Jun 15 '14 at 13:29
@yeti You're right. I use Windows atm, so couldn't remember that. Fixing... –  Seeq Jun 15 '14 at 13:39
@yeti Better now? –  Seeq Jun 15 '14 at 13:56
You can use 1e9 instead of 10**9 to save 2 characters. Also, the shebang doesn't count towards character count. –  nyuszika7h Jun 15 '14 at 14:02
@nyuszika7h That prints an extra space. –  Seeq Jun 15 '14 at 15:05

Batch (8)

type CON

Type writes file content to the console and CON is treated as a file containing all console input.

share|improve this answer

CJam - 1


No extra newline :)

share|improve this answer

16 bit .com binary for MSDOS - 31 Bytes (112 Byte NASM Source)

00 00 BA 00 00 B9 01 00 B4 3F BB 00 00 CD 21 83 F8 00 74 09 B4 40 BB 01 00 CD 21 EB EB CD 20

The nasm source code:

c:resw 1
mov dx,c
mov cx,1
mov ah,63
mov bx,0
int 33
cmp ax,0
je e
mov ah,64
mov bx,1
int 33
jmp r
int 32

Build with "nasm -f bin -o cat.com cat-msdos.s".

I already provided a solution for x86_64 Linux, but was unable to get it under 100 bytes. This is over 100 bytes of assembly, but the actually binary is only 31 bytes! This must be the simplest solution here.

share|improve this answer

Ruby, 2 bytes (or 1?)

#!/usr/bin/env ruby -p

The question states that the shabang needs to be included. The 2 bytes counted is the -p part of the shebang. The otherwise empty script makes Ruby behave exactly likes cat when run with the p switch: Run it without arguments and it will take input from stdin, or with arguments and it print the contents of those files.


Ruby, 8 bytes

@core1024 had already posted a solution in Perl similar to the one above, so here is another attempt. Note that the following are not scripts, they are Ruby programs ;)

puts *$<

Ruby, 16 bytes

I think this one is cute

print while gets
share|improve this answer

Some Perl:


25 bytes with shebang. This can also be much smaller with die(), and by bending the rules ever so slightly:


Executing the 4th test could only be done like this:

cat bla|perl ./perlcat 2>&1|diff bla -

<> is an abbreviation for <STDIN>. The 25 byte print example is pretty self explanatory. die() is normally used for exiting non-zero and outputting an error message, hence using the 2>&1 to bend the rules around the 4th test.

It also appears that the semicolon is not required for the last statement in Perl, so the first example could be brought down to 24 bytes.

share|improve this answer


While 1:Input A:Disp A:End
share|improve this answer
Does not work if a mathematical expression is entered, because it will be evaluated before it is displayed. –  Thomas Kwa May 20 at 1:12

GML, 37

share|improve this answer

Common Lisp

ECL, 106

#!/usr/local/bin/ecl -shell
(ignore-errors(loop(write-byte(read-byte *standard-input*)*standard-output*)))

SBCL, 109

#!/usr/local/bin/sbcl --script
(ignore-errors(loop(write-byte(read-byte *standard-input*)*standard-output*)))

CLISP, 188 180

(let((i(make-stream 0 :element-type'(mod 256)))(o(make-stream 1
:direction :output :element-type'(mod
256))))(ignore-errors(loop(write-byte(read-byte i)o))))

These are the shortest programs that I can make, yet none are under 100 bytes.

The main problem is that *standard-input* and *standard-output* are character streams, not byte streams. A simple (loop(write-char(read-char)) would copy the characters but would fail to preserve bytes that did not form valid characters. Now my Common Lisp implementations want to use UTF-8 (perhaps because my locale is UTF-8), but I want to copy binary files that my not be valid UTF-8. Therefore I must copy bytes, not characters.

In ECL and SBCL, standard input and output are bivalent for both bytes and characters. I may use read-byte and write-byte, but those functions lack default streams, so I must pass *standard-input* and *standard-output* as arguments.

CLISP insists that *standard-input* and *standard-output* transport only characters. The way around this is to call ext:make-stream on file descriptor 0 (standard input) and file descriptor 1 (standard output) to make binary streams.

All three programs loop byte by byte. This is a slow way to copy bytes. A faster way would use a vector of 16384 bytes with read-sequence and write-sequence, but the program would be longer.

share|improve this answer

JAVA 68 104

My first approach at this:

class a{public static void main(String[]a){System.out.print(a[0]);}}

EDIT: Yeah, I misunderstood the concept, here is another attempt, I couldn't get it done in less than 100 chars so I'd appreciate any suggestion:

class a{public static void main(String[]a)throws Exception{for(;;)System.out.write(System.in.read());}}
share|improve this answer
That's not how cat works. cat displays the contents of the file(s) given as command line arguments, or takes input from stdin when there are no arguments. –  daniero Jun 24 '14 at 23:16
@daniero Yeah I wasn't right, it works now, although much longer. –  BrunoJ Jun 25 '14 at 18:33
This breaks the rule about looping forever, how about: class a{public static void main(String[]a)throws Exception{int r;while(0<(r=System.in.read()))System.out.write(r);}} –  Roy van Rijn Sep 15 '14 at 11:29

Shell script, 11 bytes (including shebang)

share|improve this answer
XD somehow my cat was on /usr/bin/cat XD –  Kokizzu Jun 26 '14 at 10:15
This isn't technically a shell script, it's a cat script. The shell isn't involved for executables with a shebang, unless the shebang happens to point to the shell. –  nyuszika7h Jul 2 '14 at 18:20
@nyuszika7h Arguably it's a shell script that's just using cat as the shell. –  fluffy Jul 3 '14 at 5:06
But this is not a cat program. This is a quine. –  jimmy23013 Jul 4 '14 at 8:18
@user23013 Oh, so it is. –  fluffy Jul 5 '14 at 5:46

Rust - 74

Really generic...

use std::io;fn main(){for l in io::stdin().lines(){io::print(l.unwrap())}}

No Comment - 12


Unimplemented, so, yeah.

share|improve this answer

Dart - 48

share|improve this answer

Groovy - 45 bytes

#!/usr/bin/env groovy
System.out << System.in

And test:

$ cat FirstJsonObj.groovy | ./Cats.groovy | diff FirstJsonObj.groovy  -
share|improve this answer

zsh, 15 bytes


Note that there is no newline at the end of the file.

share|improve this answer

Perl6 (14):

.say for lines

And, if it doesn't need to be deterministically printing it in the correct order (hehe), you can use the auto-threading "map-apply"

share|improve this answer

Marbelous 11


How it works.

The 00 is a language literal, it represents 0, but could be exchanged for any hexadecimal value in this case. On the first tick, this value will fall down and hit \\ which is a deflector and will shove the marble to the right.

/\ is a cloner, which puts one marble to the right, back onto the deflector, this creates an infinite loop. The second copy will be placed to the right. This copy will hit the ]] device, which fetches the first character on STDIN and outputs its ascii code below. This will put the resulting marble off the botom of the board ; any marble that falls off the board gets printed to STDOUT.

In case there is nothing on STDIN, the ]] device will push the input marble too the right. There it will trigger the !! device, which terminates the board.

share|improve this answer

Tcl 57

#!/usr/bin/env expect
while {[gets stdin d]>=0} {puts $d}
share|improve this answer

grep - 2 or 7 bytes

grep ''

Tested on Linux.

The "program" of '' is two bytes but the complete command is 7 bytes.

share|improve this answer
Actually, '' as a grep program won't work (try printf "#!/bin/grep\n''" > prog; chmod +x prog; ./prog). In your example, '' is just shell quote syntax. I can't see a way to run this with grep as interpreter, so this should count as a 7-byte shell script. –  nyuszika7h Jul 2 '14 at 18:14
'' as a program will work from the interactive shell: "seq 100 | grep '' | md5sum" produces the same result as "seq 100 | md5sum" (ignore the double quotes) –  Ken A Jul 2 '14 at 18:52

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.