On Linux, you could use the immutable flag using chattr to achieve read-only on a filesystem level (requires appropriate permissions though). I don't use OS X and do not know if it has something similar, but you could achieve "after script is run, test.txt still exist" using:
#!/bin/sh mv test.txt test.bak trap "mv test.bak test.txt" EXIT rm -f test.txt
This script renames test.txt to test.bak and renames it back when the script has exited (after rm -f test.txt). This is not truly read-only, but unless you kill -KILL your script, it should preserve your data at least.
Alternative idea, if you insist having that line in it, why not exit earlier?
#!/bin/sh # do your thing exit # my boss insisted to have the 'rm' line below. rm -f test.txt
Alternative that turns rm into a function that does nothing:
#!/bin/sh # do your thing rm() { # this function does absolutely nothing : # ... but it has to contain something } rm -f test.txt
Similar to the function method above, but using the deprecated alias command to alias rm to the true built-in that does nothing (but returing a true exit code):
#!/bin/sh # do your thing alias rm=true rm -f test.txt
Alternative that removes rm from the environment (assuming that there is no rm built-in):
#!/bin/sh # do your thing PATH= # now all programs are gone, mwuahaha # gives error: bash: rm: No such file or directory rm -f test.txt
Another one that changes $PATH by using a stub rm program (using /tmp as search path):
#!/bin/sh # do your thing >/tmp/rm # create an empty "rm" file chmod +x /tmp/rm PATH=/tmp rm -f test.txt
For more information about built-ins, run help <built-in> for details. For example:
true: true Return a successful result. Exit Status: Always succeeds.
For other commands, use man rm or look in the manual page, man bash.
vaguethat reading a shell book didn't help much (yet)!