Fun with polymorphic shell scripts

Imagine you have two shell scripts in the same directory.

test1.sh:

#!/bin/bash

echo "I am test1"
cp test2.sh test1.sh

test2.sh:

#!/bin/bash

echo "I am test2"
cp test2.sh test1.sh

echo "This should not get printed"

Now run test1.sh. What do you expect the output to be?

I’d imagine that bash would run a copy of test1.sh in memory, and as a result of that execution, test1.sh would be replaced with test2.sh at the end of execution. But I would be wrong. This is the output I get after running test1.sh:

$ ./test1.sh 
I am test1
This should not get printed

What the?

2 Comments

Evan Solomon

I actually made a demo in one liner form while you were writing this:

git clone https://gist.github.com/b81f8c253cfe6724fce4.git shells-are-crazy && cd shells-are-crazy && chmod +x *.sh && ./print.sh | grep "should not get printed"
Kyle Rankin

That is completely counterintuitive. I had assumed it runs a copy in memory (and it behaves like it does this to a point):

#!/bin/bash

echo "I am test3"
stat test3.sh
rm test3.sh
stat test3.sh

echo "Should this get printed? I don't know anymore"
$ ./test3.sh 
I am test3
  File: `test3.sh'
  Size: 125       	Blocks: 24         IO Block: 4096   regular file
Device: 14h/20d	Inode: 6558960     Links: 1
Access: (0775/-rwxrwxr-x)  Uid: ( 1000/    kyle)   Gid: ( 1000/    kyle)
Access: 2013-03-01 17:48:22.337170925 -0800
Modify: 2013-03-01 17:48:13.661170924 -0800
Change: 2013-03-01 17:48:19.833171074 -0800
 Birth: -
stat: cannot stat `test3.sh': No such file or directory
Should this get printed? I don't know anymore

Name

Email (optional)

Blog (optional)