1. 新建自己的shell文件,或者中windows上传


    例如:   d:\\x.sh


1.  #! /system/bin/sh
2.  #最简单的一个shell,没什么功能
3.  #需要注意的是必须是 #! /system/bin/sh开头(有空格)
4.  #和一般linux不同,如果用#!/bin/sh就会找不到(因为没有)
5.  ls


复制代码


    在cmd中用adb push d:\\x.sh /data/kenshin上传shell


    第一个参数是本地文件位置,第二个是远程位置(也就是放在android中的位置),在根目录的data目录下,kenshin是我自己创建的一个文件夹.  如果失败了,说是只有只读权限的话,需要修改文件夹的权限.具体如下:


    进入adb shell,使用mount命令查看挂了哪些块.


1.  C:\Documents and Settings\Kenshintang>adb shell
2.  # mount
3.  mount
4.  rootfs / rootfs ro 0 0
5.  tmpfs /dev tmpfs rw,mode=755 0 0
6.  devpts /dev/pts devpts rw,mode=600 0 0
7.  proc /proc proc rw 0 0
8.  sysfs /sys sysfs rw 0 0
9.  tmpfs /sqlite_stmt_journals tmpfs rw,size=4096k 0 0
10.  /dev/block/mtdblock0 /system yaffs2 ro,noatime,nodiratime 0 0
11.  /dev/block/mtdblock1 /data yaffs2 rw,nosuid,nodev 0 0
12.  /dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0


复制代码


    比如/dev/block/mtdblock0 /system就是只读的,/dev/block/mtdblock1 /data是读写的


    修改读写权限用mount命令


    例如  mount -t yaffs2 -o remount,rw,noatime,nodiratime /dev/mtdblock0 /system 


    -o选项用来描述设备或者档案的挂接方式,常用的有


           loop:用来把一个文件当成硬盘分区挂接上系统


           ro:采用只读方式挂接设备


           rw:采用读写方式挂接设备


     具体的用法可以google linux命令mout的用法.


      上面那句话的意思就是让/system文件夹有读写的权限



2. cd到shell所在的文件夹,查看x.sh的权限,一般上传上去的话是没有执行权限的,可以用ls -l查看


    使用chmod 777 x.sh增加权限,具体可以google chmod的用法.



3. 执行   ./x.sh



4. 如何在程序中执行shell


1.  package com.kenshin.hellocommand;
2.  
3.  import java.io.BufferedReader;
4.  import java.io.IOException;
5.  import java.io.InputStream;
6.  import java.io.InputStreamReader;
7.  import android.app.Activity;
8.  import android.os.Bundle;
9.  import android.widget.TextView;
10.  
11.  public class HelloCommand extends Activity {
12.      /** Called when the activity is first created. */
13.          private TextView tv;
14.          
15.      @Override
16.      public void onCreate(Bundle savedInstanceState) {
17.          super.onCreate(savedInstanceState);
18.          setContentView(R.layout.main);
19.          tv = (TextView)findViewById(R.id.tv01);
20.          
21.          
22.          try {
23.                  execCommand("./data/kenshin/x.sh");   
24.                  } catch (IOException e) {
25.                          // TODO Auto-generated catch block
26.                          e.printStackTrace();
27.                  } 
28.      } 
29.     
30.      public void execCommand(String command) throws IOException {
31.  
32.          // start the ls command running
33.              //String[] args =  new String[]{"sh", "-c", command};
34.          Runtime runtime = Runtime.getRuntime();  
35.          Process proc = runtime.exec(command);        //这句话就是shell与高级语言间的调用
36.                                                       //如果有参数的话可以用另外一个被重载的exec方法
37.  
38.          //实际上这样执行时启动了一个子进程,它没有父进程的控制台
39.          //也就看不到输出,所以我们需要用输出流来得到shell执行后的输出
40.          InputStream inputstream = proc.getInputStream();
41.          InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
42.          BufferedReader bufferedreader = new BufferedReader(inputstreamreader);
43.  
44.          // read the ls output
45.  
46.          String line = "";
47.          StringBuilder sb = new StringBuilder(line);
48.          while ((line = bufferedreader.readLine()) != null) {
49.              //System.out.println(line);
50.                  sb.append(line);
51.                  sb.append('\n');
52.          }
53.          
54.          tv.setText(sb.toString());
55.  
56.          //使用exec执行不会等执行成功以后才返回,它会立即返回
57.          //所以在某些情况下是很要命的(比如复制文件的时候)
58.          //使用wairFor()可以等待命令执行完成以后才返回
59.          try {
60.              if (proc.waitFor() != 0) {
61.                  System.err.println("exit value = " + proc.exitValue());
62.              } 
63.          }
64.          catch (InterruptedException e) {  
65.              System.err.println(e);
66.          }
67.      }
68.  }


复制代码