Say you want to strace a script.. Well, you can’t, right? Because strace expects ELF (or other object format) executables as a target, or a running process. So one trick is to put a sleep at the top of the process, start it, do a quick ps, then strace -p.. Ugly, but effective in many cases.
Another thing you can do is grab the shebang line from the top of the script and parse it out and run strace on that and lookup the proper argument for the command interpreter that you are executing and pass all of that to strace.
Since I have to do this so frequent, and I don’t want to care about which arguments work best with which interpreters, I wrote a little C generalized wrapper that reexecs the program I’m interested.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <string.h>
main (int argc, char *argv[]) {
char *argvp[3];
char line[MAXPATHLEN];
int i;
if (argc < 2) {
puts ("usage: reeexec [ args ]");
exit(1);
}
if (argvp == NULL) {
perror("error allocating for argvp");
exit(1);
}
for (i = 1; i < argc; i++) {
strcat(line, argv[i]);
strcat(line, " ");
}
execl("/bin/bash", "bash", "-c", line, (char *) NULL);
}
usage:
strace -f -e trace=open,execve /usr/local/bin/reexec /opt/topspin/bin/smroute node1 node1024
Normally, I’d want to run strace on smroute directly, but it’s a python script, so I call reexec and it takes all the other arguments and concatenates them together and executes bash on the results. (plain old sh would do too).
It’s quick and dirty and might not handle certain variable escaping or special character things too well, but it works for most things. Hope somebody else finds it useful.