Yesterday I had a major debugging problem when one of my tests refused to pass. It just happened that this test covered the major functionality of what I had been working on for the previous 10 hours.
This part of the code called a command line utility to fill a form in a pdf. It refused to work. It would work when I tested it on the command line; it would work when I tested it from my cygwin console; it worked when I created a unit test.
Finally I found the problem: it was the forward slashes. When you are in php, php takes care of the forward slashes for you. The same thing with the cygwin console. However, when I used the exec() command, it obviously was back in the windows world from where I am developing, so it wouldn't work.
So here is my hard earned checklist on troubleshooting command line commands in scripting languages via exec() or equivalent.
0. Does your the command string run on the native command line?
grep 'tasty pies' pgtips.txt
'grep' is not recognized as an internal or external command, operable command or batch file.
(Or our command line command complaining about lacking something, such as lack of parameters or permissions)
1. Do you have all of the arguments in your command string?
Example: exec("grep 'tasty pies' "); #Ouch! We forgot to put the directory!
2. Do you have spaces in between your command string?
$pattern = 'tasty pies';
exec('grep' . $pattern); #No spaces. The concatenated string is 'greptasty pies'. There is no such command called greptasty, that I know. Not a bad name for a unix utility, actually.
3. Does it work from the working directory?
exec("grep 'tasty pies' pgtips.txt ");
4. Does it work if you use a path to it?
exec('grep 'tasty pies' uk/tea/pgtips.txt');
5. Are the slashes correct for your os?
exec("grep 'tasty pies' uk/tea/pgtips.txt"); #This is wrong if you are working in Windows!
6. Does the user executing the script has the right permissions to do it?
Troubleshoot this via unit tests.
Obviously one cannot unit test the tests performed directly on the command line, but since it is only one and quickly done, it shouldn't be a big deal. The reason why you should write tests is because it will document what you have tried. Hard to crack problems makes us lose perspective, and we often try to do the same test again and again.
By writing a unit test, you will have will have it tested again and again, but one won't forget about it for a few minutes only to try it again as a possible solution later 10 minutes later. Because of this, it should reduce the troubleshooting time. In my case, I only figured the problem out once I began methodically writing tests for the scenarios that I wrote above.