My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
ShellCommands  
How to drop the shell commands
Phase-Design
Updated Aug 23, 2010 by michel.racic

Problem

There exist certain ways how to drop a shell command from an application. Some of them end in force close on some circumstances.

Existing solution

Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
DataInputStream osRes = new DataInputStream(process.getInputStream());
for (String single : commands) {
   os.writeBytes(single + "\n");
   os.flush();
   res.add(osRes.readLine());
}
os.writeBytes("exit\n");
os.flush();
process.waitFor();

prior solution from rac

found this here

Class<?> execClass = Class.forName("android.os.Exec");
Method createSubprocess = execClass.getMethod("createSubprocess",
	String.class, String.class, String.class, int[].class);
Method waitFor = execClass.getMethod("waitFor", int.class);
// Executes the command.
// NOTE: createSubprocess() is asynchronous.
int[] pid = new int[1];
FileDescriptor fd = (FileDescriptor)createSubprocess.invoke(
        		null, arg0, arg1, arg2, pid);
// Waits for the command to finish.
waitFor.invoke(null, pid[0]);

ideas

Execute trough a shell script

The application ships with a generic shell script and a normal shell command will be dropped.

#!/system/bin/sh
# MarketEnabler example set script
# Usage: has to be called with all the values as arguments
setprop gsm.sim.operator.numeric $1
setprop gsm.operator.numeric $2
setprop gsm.sim.operator.iso-country $3
setprop gsm.operator.iso-country $4
setprop gsm.operator.alpha $5
setprop gsm.sim.operator.alpha $6
kill $(ps | grep vending | tr -s ' ' | cut -d ' ' -f2)
rm -rf /data/data/com.android.vending/cache/* 

As I played on my phone with different ways to execute this commands, this was the only way that executed the commands all times and very fast.

Using API for getting values and setting of some values

Setting operator values (untested):

android.telephony.ServiceState.setOperatorName(String longName, String shortName, String numeric)

Getting values (working):

TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
tm.getNetworkCountryIso()
tm.getNetworkOperator()
tm.getNetworkOperatorName()
tm.getSimCountryIso()
tm.getSimOperator()
tm.getSimOperatorName()

Set values can maybe done trough android.os.SystemProperties.set(String key, String val) <== not anymore in 1.5

Comment by UC.dev.n...@gmail.com, Oct 14, 2009

Thank you thank you thank you! this Runtime.getRuntime() thing just saved me another week of bashing my head against the wall.

Comment by project member michel.racic, Oct 15, 2009

your welcome Just be aware thet if you're executing the su command and the superuser.apk is installed it can lead to force closes.

Comment by joaoh88, Jan 26, 2010

I'm having troubles reading osRes.readLine() when the result has more than one line, I tried with "while (( line = osRes.ReadLine?() ) != null) { ... }" but it hangs forever, don't even makes the app to force close!

Comment by project member michel.racic, Jan 26, 2010

because it never gets null... read the API line = osRes.Readline() will wait for the next line to be completed and then return, if the InputStream? never makes a new line or just is not returning any data it will wait forever. In your case a BufferedReader? would be the better thing...

Comment by asifk1...@gmail.com, Feb 2, 2010

Shell script is given but How can we execute this script form command line I have tried with following but no success yet, Process process = Runtime.getRuntime().exec("/data/busybox/my_script.sh");

Comment by project member michel.racic, Feb 2, 2010

have you altered the file to be executable? chmod +x /data/busybox/my_script.sh Otherwise its a normal text file that doesnt have permission to be executed

Comment by sudhir.v...@gmail.com, Feb 4, 2010

Hiii,

can some one elaborate on :

Process process = Runtime.getRuntime().exec("su"); DataOutputStream? os = new DataOutputStream?(process.getOutputStream()); DataInputStream? osRes = new DataInputStream?(process.getInputStream()); for (String single : commands) {

os.writeBytes(single + "\n"); os.flush(); res.add(osRes.readLine());
} os.writeBytes("exit\n"); os.flush(); process.waitFor();

i tried to run this app, it says:

cannot iterate on Command , and res cannot be resolved.

I used to run the exec , happily until Android 2.0 came up, which is not letting me run any shell commands through application.

Thanks for the help, great idea for an application :)

Comment by project member michel.racic, Feb 5, 2010

res is just a String vector... osRes.readLine() is the only interesting... As MarketEnabler? works on Nexus, I assume that the code is still working ;-) maybe you try the reflection method

Comment by sudhir.v...@gmail.com, Feb 5, 2010

Thanks Micheal, i resolved the res , thingy , i directed it to outputview . i still have one error, what is "command" in here. i am geting an error at "String single : command"

thanky.... I am building the app for Droid. 2.0.1 Android.

Sudhir

Comment by asifk1...@gmail.com, Feb 7, 2010

I have tried the existing solution as bellow and my command is "ifconfig wlan0 up" which need "su" permission so it need to run in the same process as that of "su". I have tried this solution as android application but it breaks at the following line

"os.writeBytes(single + "\n");

and exception is "broken pipe : IO exception" Can anyone help me please??

Existing Solution

Process process = Runtime.getRuntime().exec("su"); DataOutputStream? os = new DataOutputStream?(process.getOutputStream()); DataInputStream? osRes = new DataInputStream?(process.getInputStream()); for (String single : commands) {

os.writeBytes(single + "\n"); os.flush(); res.add(osRes.readLine());
} os.writeBytes("exit\n"); os.flush(); process.waitFor();

Comment by jaydip...@gmail.com, Apr 12, 2010

hi all.

I have a application in which I want to make directory in sdcard from my application. but nothing happen..

can anybody help me??

my code is

public class process extends Activity {

/ Called when the activity is first created. / @Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main);
String str ={"mkdir","/sdcard/xyz"};
try {
Process ps = Runtime.getRuntime().exec(str); try {
ps.waitFor();
} catch (InterruptedException? e) {
// TODO Auto-generated catch block e.printStackTrace();
}
}
catch (IOException e) {
Toast.makeText(this, ""+e, Toast.LENGTH_LONG).show();
}
}
}

Comment by project member michel.racic, Apr 25, 2010

@sudhir.vissa the command variable is a String array, each line you want to be executed is a new Strings object in this array.

@asifk1234 Why you dont use the API for enabling wlan?

@jaydip.ce Better use the API for this

Comment by eeg...@gmail.com, Aug 6, 2010

I have the same problem with a broken pipe from above. Any ideas as to why that is happening?

Comment by eeg...@gmail.com, Aug 10, 2010

broken pipe appears to be a problem with the emulator not allowing su

Comment by pschlaepfer@gmail.com, Nov 15, 2010

On my Nexus One (not rooted), I get the following exception: "java.io.IOException: Error running exec(). Command: su? Working Directory: null Environment: null"

Any ideas? Does this need root? Does this still work with Froyo? :-)

Comment by project member sbara...@gmail.com, Nov 15, 2010
Comment by pschlaepfer@gmail.com, Nov 16, 2010

Thanks for your quick reply! I'll look into that. I just rooted my device, that was easy :-)

Comment by android....@gmail.com, Feb 25, 2011

Thanks a lot ! that really helped. Based on your solution, I constructed a more general class that can be easily used to execute shell commands as root at the following link: http://muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html

Comment by hilffore...@gmail.com, Apr 1, 2011

thnks for the code, it really help to access the cell

i need to copy file from /data/data/com.android.providers.contacts/databases/contacts2.db

i want to use command "cat" for copying file to my sdcard

could you give me some example to do this one? please i really need it.

before that i had try to copy using class file stream, but still don't work.

Thank you very much

Hendra-1

Comment by himanshu...@gmail.com, Aug 31, 2011

java.io.IOException: Error running exec(). Command: su? Working Directory: null Environment: null

This is what i am getting when i am trying to use shellinterface as someone mentioned we need root access how to get that , does it mean we need to break Android OS? if we does not want to do that still i can run different command ?? thanks

Comment by vinu....@gmail.com, Mar 20, 2013

I think you forgot the permission of writing in to sd card in your manifest file.

By Vinod ( vinu.809@gmail.com)


Sign in to add a comment
Powered by Google Project Hosting