Coder Social home page Coder Social logo

ktsh's Introduction

Entrepreneurial Software Engineer // Founder & CEO at GoatBytes.IO // Android Enthusiast

LinkedIn StackOverflow X (Twitter) GitHub GitHub User's stars

ktsh's People

Contributors

jaredrummler avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ktsh's Issues

Continuesly reading command output

First, thank you for this valuable lib!

I want to run a command, keep it running in the background and read the from stdout/stderr.

Is this something I can do with this libs? I have been looking at the code but I couldn't find out how to do that.

Can we have a wiki?

i took me quite a bit of a time and effort to figure out, how to execute command with root permission(figured out at last by reading closed issue). Since i tried su along with my command, however my command wont execute due to permissioin issue. Had to use Shell.SU
I can contribute, as i figure things out.

RxJava Backends

Request to have RxJava backends, so that we can asynchronously run a pipeline of commands. Is this possible?

pm unistall is not working

Remove system app is failed
CommandResult result = Shell.SU.run("pm uninstall " + ai.packageName);
return "Failed" on rooted device

Sample apk

From where i can download sample apk?

Run from .sh file

Can I execute .sh files? If yes, can you link me to that guide? Thanks!

Basic Usage returns me permission denied

Hi @jaredrummler,

I'm trying this command:

val shell = Shell("sh")  // or sh -l
val result = shell.run("ls") 
if (result.isSuccess) {
    println(result.stdout())
}

and it's returning me on the stderr an error of permission denied.

Whats wrong?

thank you

commandResult.exitCode return -1

I am trying to get hash value using MD5sum using Shell.SU.run() method.
but the result always returns -1, and isSuccessful() method not called.

       var result:String? = null
        val hashCommand = Shell.SU.run("md5sum $path")
        Log.d("getHash", "Path : $path, Before : " + hashCommand.stdout.toString() + ", Error : " + hashCommand.stderr + ", Exit Code : " + hashCommand.exitCode)
        if (hashCommand.isSuccessful) {
            result =  hashCommand.stdout.toString()
            Log.d("getHash", "Path : $path, Success : " + hashCommand.stdout.toString() + ", Error : " + hashCommand.stderr)
        }
        Log.d("getHash", "Path : $path, Last : " + hashCommand.stdout.toString() + ", Error : " + hashCommand.stderr + ", Exit Code : " + hashCommand.exitCode)
       

OnCommandResultListener.onCommandResult() is called prematurely

I'm using AndroidShell for an rsync app, and almost immediately after invoking rsync, the OnCommandResultListener that I pass to Shell.Builder.open() has its onCommandResult() called. The command can continue running for several minutes thereafter. I see the same behavior if I run "top" instead of "rsync" so it doesn't appear to be tied to any specific long-running command.

Expose shell.state variable

Shell state is private but it would be useful to add an accessor for use in a when statement (as shown in the docs).

unable to set HOME in root shell environment

Using Shell.Builder(), I can set HOME via addEnvironment() when I call useSH() but not when I call useSU(). I tested by invoking "env" as the shell command.

The same value I'm trying to assign to HOME can be assigned to different keys, so it's not a problem with the value itself. I can also set HOME in a root shell in adb.

I tried this in Android 4.4 and 8.0.0, and I assume any version in the middle is the same way.

Shell.Builder Class

Please provide an example that how to use Shell.builder() class, and how to reset shell
or How to use multiple commands at once using this library.

Question: Interacting with the script/command

Greetings!
Thanks for creating this great library!
as the title itself, this is not a issue or a bug but a question regarding on how to interact with the script/command

command/script:
echo "How old are you?"
read -p age
echo "so your age is "$age

2 scenario:

Scenario A:(putting it on shell script (*.sh file))
Steps:

  • copy the script to /data/data/package_name/home
  • adding proper permission using chmod
  • running the script
    Result:
    it will stdout/err at once:(something looks like below)
    How old are you?
    read rand_id
    so your age is age_rand_id
    (random generated id/text = rand_id)
    and when you submit another command it will not stdout/err or any output

Scenario 2:(adding the command libe by line)
from the start, executing echo will work : "How old are you?"
but executing read command it will not display any output or stdout/err...
and when you submit another command it will not stdout/err or any output

Big question: how should I tackle this?

and I also notice this in some unfinished command and for loop command(assuming that you will put the command line by line), and it seems you partly added the behaviour that I want (interact with script) but it seems it only works in if-else statement.

Lib_ver: the current/latest jar as of june 2023
Phone: android 9, aarch64,Armv8a, not-rooted

Thanks and regards,
STICKnoLOGIC

how can I check I got su permission

I use supersu to manager su request.

And how can I check I have already got su permission.

Sorry for my poor English. Any point need explain?

onStdOut not properly working

Btw as mentioned in an issue#14
app is not responsive until command finishes and ping just continues to run

I'm using in jetpack compose as this

var test by remember { mutableStateOf("initial test string") }
Text(text = test)
LaunchedEffect(Unit) {
Shell.SU.run("ping google.com") {
onStdOut = { line: String ->
test = line
}
timeout = Shell.Timeout(1, TimeUnit.MILLISECONDS)
}
}

and the issue is unless I specify timeout, shell doesn't return anything

How to set Device Owner

How can I execute below permissions

val result = Shell.SH.run("adb shell dpm set-device-owner com.app.test/.AppAdminReceiver") as CommandResult

Exception in thread "main" com.jaredrummler.ktsh.Shell$NotFoundException on Windows

I'm not sure if I'm doing something wrong here, but I got this error on a simple kotlin project.

Exception in thread "main" com.jaredrummler.ktsh.Shell$NotFoundException: Error opening shell: 'sh'
	at com.jaredrummler.ktsh.Shell.<init>(Shell.kt:95)
	at com.jaredrummler.ktsh.Shell.<init>(Shell.kt:52)
	at com.jaredrummler.ktsh.Shell$Companion.get(Shell.kt:761)
	at com.jaredrummler.ktsh.Shell$Companion.getSH(Shell.kt:766)
	at MainKt.main(Main.kt:4)
	at MainKt.main(Main.kt)
Caused by: java.io.IOException: Cannot run program "sh": CreateProcess error=2, The system cannot find the file specified
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1143)
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1073)
	at java.base/java.lang.Runtime.exec(Runtime.java:615)
	at java.base/java.lang.Runtime.exec(Runtime.java:439)
	at java.base/java.lang.Runtime.exec(Runtime.java:370)
	at com.jaredrummler.ktsh.Shell$Companion.runWithEnv(Shell.kt:784)
	at com.jaredrummler.ktsh.Shell$Companion.access$runWithEnv(Shell.kt:746)
	at com.jaredrummler.ktsh.Shell.<init>(Shell.kt:90)
	... 5 more
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
	at java.base/java.lang.ProcessImpl.create(Native Method)
	at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:494)
	at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:159)
	at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1110)
	... 12 more

Process finished with exit code 1
import com.jaredrummler.ktsh.Shell

fun main() {
    val shell = Shell.SH                       // create a shell
    val result = shell.run("echo 'Hello, World!'")  // execute a command
    if (result.isSuccess) {                         // check if the exit-code was 0
        println(result.stdout())                    // prints "Hello, World!"
    }
}

MessageQueue: Handler (android.os.Handler) {cdcc738} sending message to a Handler on a dead thread

11-28 07:00:33.699 W/art: Long monitor contention event with owner method=int libcore.io.Posix.readBytes(java.io.FileDescriptor, java.lang.Object, int, int) from Posix.java:4294967294 waiters=0 for 14.898s
11-28 07:00:33.705 W/art: Long monitor contention event with owner method=void java.io.FileInputStream.close() from FileInputStream.java:114 waiters=0 for 14.904s
11-28 07:00:33.705 W/art: Long monitor contention event with owner method=void java.io.FileInputStream.close() from FileInputStream.java:114 waiters=1 for 14.838s
11-28 07:00:33.706 W/art: Long monitor contention event with owner method=void java.lang.Object.wait!() from Object.java:4294967294 waiters=0 for 31.268s
11-28 07:00:33.723 W/MessageQueue: Handler (android.os.Handler) {cdcc738} sending message to a Handler on a dead thread
    java.lang.IllegalStateException: Handler (android.os.Handler) {cdcc738} sending message to a Handler on a dead thread
        at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
        at android.os.Handler.enqueueMessage(Handler.java:631)
        at android.os.Handler.sendMessageAtTime(Handler.java:600)
        at android.os.Handler.sendMessageDelayed(Handler.java:570)
        at android.os.Handler.post(Handler.java:326)
        at com.jaredrummler.android.shell.Shell$Interactive.postCallback(Shell.java:1383)
        at com.jaredrummler.android.shell.Shell$Interactive.runNextCommand(Shell.java:1289)
        at com.jaredrummler.android.shell.Shell$Interactive.runNextCommand(Shell.java:1178)
        at com.jaredrummler.android.shell.Shell$Interactive.addCommand(Shell.java:1151)
        at com.jaredrummler.android.shell.Shell$Console.run(Shell.java:1761)
        at com.jaredrummler.android.shell.Shell$SU.run(Shell.java:374)

Command that needs WRITE_SECURE_SETTINGS permission won't work even if permission is granted

From other apps I know that they can set the screen size (which is done via wm overscan <LEFT>,<TOP>,<RIGHT>,<BOTTOM> from within the app after you have granted android.permission.WRITE_SECURE_SETTINGS to those apps.

Any ideas how I can "forward" this permission to the shell? I thought the shell will have the same permission and UID as my app, but I can't get to work what other apps can do.

My simple test case looks like following:

val test: (Int, String) -> Unit = { index, command ->
	val res = Shell.SH.run(command)
	L.d { "Result $index: ${res.isSuccessful} | ${res.exitCode} | ${res.getStdout()} | ${res.getStderr()}" }
}

val commands = arrayOf(
		"wm overscan 0,0,0,$overscanOffset",
		"settings get global policy_control",
		"echo \$PATH",
		"echo Some echod text",
		"id"
)
var c = 1
for (command in commands) {
	test(c++, command)
}
Shell.SH.closeConsole()

And the output is following:

2019-03-12 08:53:13.682 D/[UITuner$setOverscanStatus$test:56 invoke]: Result 1: false | 20 |  | cmd: Can't find service: window (UITuner.kt:56)
2019-03-12 08:53:13.714 D/[UITuner$setOverscanStatus$test:56 invoke]: Result 2: false | 255 |  | Security exception: You either need MANAGE_USERS or CREATE_USERS permission to: query user (UITuner.kt:56)
    
    java.lang.SecurityException: You either need MANAGE_USERS or CREATE_USERS permission to: query user
        at com.android.server.pm.UserManagerService.checkManageOrCreateUsersPermission(UserManagerService.java:2097)
        at com.android.server.pm.UserManagerService.getUserInfo(UserManagerService.java:1250)
        at android.os.UserManager.getUserInfo(UserManager.java:1636)
        at com.android.providers.settings.SettingsService$MyShellCommand.onCommand(SettingsService.java:273)
        at android.os.ShellCommand.exec(ShellCommand.java:103)
        at com.android.providers.settings.SettingsService.onShellCommand(SettingsService.java:51)
        at android.os.Binder.shellCommand(Binder.java:642)
        at android.os.Binder.onTransact(Binder.java:540)
        at android.os.Binder.execTransact(Binder.java:739)
2019-03-12 08:53:13.727 D/[UITuner$setOverscanStatus$test:56 invoke]: Result 3: true | 0 | /sbin:/system/sbin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin |  (UITuner.kt:56)
2019-03-12 08:53:13.741 D/[UITuner$setOverscanStatus$test:56 invoke]: Result 4: true | 0 | Some echod text |  (UITuner.kt:56)
2019-03-12 08:53:13.764 D/[UITuner$setOverscanStatus$test:56 invoke]: Result 5: true | 0 | uid=10290(u0_a290) gid=10290(u0_a290) groups=10290(u0_a290),9997(everybody),20290(u0_a290_cache),50290(all_a290) context=u:r:untrusted_app:s0:c34,c257,c512,c768 |  (UITuner.kt:56)

I'm not sure if test 2 can succeed (have not seen an app doing it yet), but test 1 can succeed on unrooted devices if android.permission.WRITE_SECURE_SETTINGS is granted to the app.

Do you have any ideas, why I instead get the Can't find service: window although the same command works perfectly fine from an adb command line? I would expect an exception, if a permission is missing, but not the can't find error... I'm not sure at all if WRITE_SECURE_SETTINGS and shell commands can work together at all, any ideas if this is even possible?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.