Yes, I just use the builtin's. Basically os.execute, and io.popen.
Popen is not the greatest because you can't get exit statuses from it. But for a quick script that is too messy in shell, it suffices. I believe that there is an extension to lua that has a popen that returns exit statuses. That can be used too.
For pattern matching, I either pipe to perl and capture the output, or use the inbuilt pattern matching system. It's surprisingly powerful.