歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> SHELL編程

如何讓Android系統或Android應用執行shell腳本

一、Android應用啟動服務執行腳本

1 如何寫服務和腳本

在android源碼根目錄下有/device/tegatech/tegav2/init.rc文件相信大家對這個文件都不陌生(如果不明白就仔細研讀下android啟動流程)。如果在該腳本文件中添加諸如以下服務:

service  usblp_test  /data/setip/init.usblpmod.sh

oneshot

disabled

注解:每個設備下都會有自己對應的init.rc,init.設備名.rc腳本文件。oneshot disabled向我們說明了在系統啟動的時候這個服務是不會自動啟動的。並且該服務的目的是執行/data/setip/init.usblpmod.sh腳本。腳本的內容你可以隨便寫,只要符合shell語法就可以了,比如腳本可以是簡單的設置eth0:

# ! /system/bin/sh //腳本的開頭必須這樣寫。

Ifconfig eth0 172.16.100.206 netmask 255.255.0.0 up//設置ip的命令

2、如何在應用中啟動服務

1)首先了解下在服務啟動的流程

1.    在你的應用中讓init.rc中添加的服務啟動起來。

首先了解下在服務啟動的流程:

在設備目錄下的init.c(切記並不是system/core/init/init.rc)

Main函數的for(;;)循環中有一個handle_property_set_fd(),函數:

      for (i = 0; i < fd_count; i++) {
            if (ufds[i].revents == POLLIN) {
                if (ufds[i].fd == get_property_set_fd())
                    handle_property_set_fd();
                else if (ufds[i].fd == get_keychord_fd())
                    handle_keychord();
                else if (ufds[i].fd == get_signal_fd())
                    handle_signal();
            }
        }

這個函數的實現也在system/core/init目錄下,該函數中的check_control_perms(msg.value, cr.uid, cr.gid)函數就是檢查該uid是否有權限啟動服務(msg.value就是你服務的名字),如果應用為root或system用戶則直接返回1.之後就是調用handle_control_message((char*) msg.name + 4, (char*) msg.value),該函數的參數就是去掉1.ctl.後的start和2.你服務的名字。這個函數的詳細內容:

void handle_control_message(const char *msg, const char *arg)
{
    if (!strcmp(msg,"start")) {
        msg_start(arg);
    } else if (!strcmp(msg,"stop")) {
        msg_stop(arg);
    } else if (!strcmp(msg,"restart")) {
        msg_stop(arg);
        msg_start(arg);
    } else {
        ERROR("unknown control msg '%s'\n", msg);
    }
}

匹配start後調用msg_start.服務就這樣起來了,我們的解決方案就是在檢查權限的地方“下點功夫”,因為我們不確定uid,所以就讓check_control_perms這個函數不要檢查我們的uid,直接檢查我們服務的名字,看看這個函數:

static int check_control_perms(const char *name, unsigned int uid, unsigned int gid) {
    int i;
    if (uid == AID_SYSTEM || uid == AID_ROOT)
        return 1;

    /* Search the ACL */
    for (i = 0; control_perms[i].service; i++) {
        if (strcmp(control_perms[i].service, name) == 0) {
            if ((uid && control_perms[i].uid == uid) ||
                (gid && control_perms[i].gid == gid)) {
                return 1;
            }
        }
    }
    return 0;
}

這個函數裡面是必須要檢查uid的,我們只要在for循環上寫上。

if(strcmp(“usblp_test”,name)==0) //usblp_test就是我們服務的名字。

        return 1;

這樣做不會破壞android原本的結構,不會有什麼副作用。

init.c和init.rc都改好了,現在就可以編譯源碼了,編譯好了裝到機子開發板上就可以了。

Copyright © Linux教程網 All Rights Reserved