Below is the command I tried executing, without success:
exec('ln -s ' . PLUGIN_DIR . '/.htaccess ' . ABSPATH . '/.htaccess');
When you add a die() at the end, it catches that there's an error:
exec('ln -s ' . PLUGIN_DIR . '/.htaccess ' . ABSPATH . '/.htaccess') or die('what?!');
For the above exec() statement, a permissions problem is causing the error, but PHP isn't displaying it. How do you display from PHP what error is occurring?
You can receive the output result of the exec function by passing an optional second parameter:
exec('ln -s ' . PLUGIN_DIR . '/.htaccess ' . ABSPATH . '/.htaccess',$output);
var_dump($output);