Anything that can reasonably called Unix or Unix-like has POSIX utilities. You can generally assume that the utilities are present, that they support the listed options, and that they behave as indicated. There are a few limitations:
- Features that are marked as optional may not be present everywhere.
- Recently added features may not be present everywhere yet. Check the “change history” section.
- Software has bugs. Any given system usually deviates from the specification in a few corner cases. And sometimes the developers or the distribution maintainers don't care about deviating from the specification. There's no way to find that out other than from experience.
Here are limitations that you're likely to run into on many Linux distributions:
pax are often missing from the default installation.
- Corner cases of job control tend to behave weirdly outside of ksh.
If you limit to non-embedded Linux, you can make some additional assumptions.
- Most distributions follow the Filesystem Hierarchy Standard, which mandates a number of utilities beyond POSIX.
- Bash is available. But
/bin/sh might not be bash.
- Most POSIX utilities are the GNU coreutils implementation, which offers quite a few extensions.
- util-linux is available (but a few utilities may be replaced by another implementation of a utility with the same name and possibly with different options).
On embedded Linux, the shell and utilities are usually from BusyBox. Because BusyBox is intended for small systems, it deliberately omits some features, including features that are mandated by POSIX. BusyBox has a lot of compile-time configuration options, so you can't really anticipate what will be available on a given system. If you want to maximize portability to embedded Linux, when you use a utility, look at its source code in BusyBox and avoid options that are under a conditional compilation guard. This won't help if an installation is missing that utility altogether though.