Okay, here are some:

Be aware of how the init/startup system works on the machines your software is going to be deployed to. If you're writing a long running network service, then this means providing an init.d script that provides at least start, stop, restart, and status actions. Learn enough of shell scripting to write this script in sh or bash, not in some more heavyweight language like python or perl or php or ruby.

Write services that don't need to be running as root and/or know how to cease being root after their setup stage. Don't hardcode any settings (like port being listened on, or user to run as). Make a config file. And don't make it XML. Make it easy to build a package, deb or rpm, by providing the necessary debian/ dir contents or .spec file.

When the systems team says there's a bug in your code, fix it. If you don't, you risk having the notifications for the failed service being sent to your phone waking you up. When code is changing all the time, there's more likely to be a bug in your code than there is to have a random system configuration or hardware issue. In many cases, machines with hardware problems are most likely already removed from service before you even know about it.

Don't make the systems team debug your code and provide a patch. I know a lot of developers who think systems people don't/can't program or they only know how to "script"; that's not true, being able to program is one thing that, I think, is required to be on the systems team. We'll help you debug and provide the tools to get things resolved, but we shouldn't have patch your code for you.

Don't write services that keep a lot of internal, in-memory state that isn't saved to disk periodically such that it can't pick up where it left off if it is restarted.

Do write services that allow easy introspection into its state. The memcached "stats" command is an example. This allows us to easily hook your code into things like ganglia. Some programs, when sent a signal, dump info to a log file.

Speaking of log files, use techniques to detect if your log file has changed and reopen it if its rotated (stat(logfilename) != fstat(logfilefd)).

Those who don't learn /bin and /usr/bin are doomed to reinvent them, poorly. Don't waste time reimplementing things that already exist. Like xargs. Or head. Or wc. Or yes. Or host. Or watch.

Learn how to use the stuff in binutils, like objdump, nm and strings.

Don't write scripts in python or perl or ruby or php that do some weird setup (like parsing command line arguments) and then just invoke something via the shell with system(). On the off chance you do need to do this, use exec instead.

Don't name scripts that might be integrated with other tools or batch jobs with a language specific extension (unless this is required by your platform, cough ahem) or it's a language specific library. Reserve .py for python modules, for example. The reason here is that your perl script might be rewritten as ruby one day or optimized by porting it to C, and there might be stuff calling it, and then you end up with a ruby script named .pl. We don't name C binaries ending with a .c extension, your "production" scripts are logically "binaries" if not physically. (I've actually run across this).

Use or create proper library routines to access structured data files. As a contrived example, use getpwent, don't parse /etc/passwd by yourself.

Put a password on your ssh private key.

Don't architect distributed things that require passwordless ssh keys to run. If you need to distribute files to a bunch of machines, they should be pulled from an rsync or http server, rather than via scp or remoting invoking rsync over ssh.

Learn about sudo, because you're going to have to use it.

Learn the difference between tmpnam, mktemp and mkstemp, and why you should use mkstemp.

Honor the TMPDIR environment variable.

Don't fill up the disks. When you get automated quota emails, do something about it.

Don't work around the limits that have been put in place on systems, they are most likely there for a reason; if you are hitting a limit, we're open to having them changed. For example, if there's a 4 gig address space limit on a machine for user xyz, don't work around that by changing the user your code runs as.

Write runbook documentation. This means somewhat of a Q&A style "How do I..." or "What to do when X, Y, Z". Make them easy to visually scan, make keywords standout. Hopefully, your systems team has provided a place for these to be stored that is easily accessible and easy to update. A lot of people get bogged down when writing documentation, trying to figure out what's appropriate to document. A runbook, which is a living document, makes this easier, because it's obvious that you add to it as problems or corner cases crop up.

I'm sure I could come up with some more.