Android has its own init
system with a special init.rc
configuration
file. This file uses its own syntax which, unlike shell scripts used
in classical sysvinit
, does not allow you to do everything you might
need. Instead, it has its own (rather limited) set of actions that it
can do (like mkdir
, chmod
, chown
, etc). There is, however, exec
keyword defined that should execute specified command (could be a shell
script) but unfortunately, it is not implemented (I mean, the keyword is
recognized by it does nothing).
The situation was weird to me first time I saw it (back in Android 2.2)
but since implementing basic exec
action is not really hard, I just
added it to the android init
system without much thinking and was
using it for some time now. It can be something like:
void exec_start(int nargs, char** args)
{
pid_t pid;
int status, i;
if (nargs < 2 || args == NULL) return;
args++;
pid=fork();
if(pid == 0) {
execvp(args[0], args);
ERROR("Exec (%s) failed \n", args[0]);
_exit(1);
} else if(pid > 0) {
waitpid(pid, &status, 0);
INFO("Child exited with status %d \n", status);
} else {
ERROR("Failed to start '%s'\n", args[0]);
}
}
This made it possible to do something like
this in init.rc
:
chmod 0750 /system/bin/script.sh
exec /system/bin/script.sh
The init system runs script.sh
script and blocks until it finishes.
The devices I’m working on right now are based on Android 4.0 which is
still missing exec
implementation by default. This made me rethink the
whole problem again. Am I the only person who wants to run some shell
scripts in init.rc
on Android? Then I figured out that it is possible
to do this in default Android init.rc
- we can use init’s service
concept:
chmod 0750 /system/bin/script.sh
start script
[...]
service script /system/bin/script.sh
disabled
oneshot
It does need some more lines and makes it less readable for me (the
actual executable path is in different place of the file than the call
that uses it) but it definitely works. As an added bonus, you get all
the environment variables (like very useful ANDROID_PROPERTY_WORKSPACE
or BOOTCLASSPATH
) properly set without thinking about it when
implementing exec
action (this is missing in my simple implementation
of exec
) and restarting of the script if it dies (if you need it).
It’s so simple, I don’t know why I didn’t use this from the start.