How to remove file on android using ADB - android

I am trying to remove a file on my android using a single ADB command.
I understand you can just do adb shell and then remove the file using rm.
But I need it to be a one line execution.
I’ve tried:
adb rm-f /directory/file.txt
adb shell rm-f /directory/file.txt
Both don’t delete the file I want.

Delete file on android:
adb shell rm sdcard/download/file.ext

I noticed in your comments you are looking for one line execution since you're gonna be using Python. Well as an alternative you could use the subprocess module to write to stdout allowing you to execute as many commands of choice
for example
import subprocess
process = subprocess.Popen([r'adb', 'arg1', 'arg2'], stdout=subprocess.PIPE,stdin=
subprocess.PIPE) #start adb
process.stdin.write('shell \n') # Parse in input into the program
process.stdin.write('rm *\n') # Parse in second input
line=process.stdout.readline() # Read a line from stdout

It worked for me to run the following command:
adb shell rm -f -rR -v /sdcard/Documents/

Related

adb push in a script

I have a simple bash script to push an executable to the android and then remove it.
#!/bin/bash
adb push CMakeBuild_Android_armv8/Out/Release/exec /data/local/tmp/exec
adb shell rm data/local/tmp/exec
This is saved as 'adb_push.sh'. I made sure that this is an executable via chmod.
chmod +x adb_push.sh
But when I run this script in the Cygwin ./adb_push.sh, I get an error that there is no such directory.
CMakeBuild_Android_armv8/Out/Release/exec: 1 file pushed, 0 skipped. 62.5 MB/s (7302616 bytes in 0.111s)
rm: data/local/tmp/exec: No such file or directory
Is there any obvious steps that I am missing in creating a bash script or is there any error in what I am doing?
Any hint or comment would be highly appreciated.
ADB version:
$ adb version
Android Debug Bridge version 1.0.41
Version 31.0.0-7110759
Installed as C:\platform-tools_r31.0.0-windows\platform-tools\adb.exe
Disclaimer: I already tried putting the source and destination path in quotes, it did not work for me. Also tried the same with a .wav file instead of an executable and I get the same error which lead me to believe that something's not right in the bash script.
Your second command assumes the working directory is the root /. It appears this assumption is false.
The first command is succeeding. Only the second command is failing.
If adb shell doesn't start at the root (/), then the destination path you supply in the first command (/data/local/tmp/exec) is different from the path you supply in the second command (data/local/tmp/exec, note the missing slash at the beginning).
I'm gonna guess adb shell on your device starts a shell in some user's home directory, not /.
Option 1: Use absolute file path
You can fix this by giving the full absolute file path in your second command:
adb shell rm /data/local/tmp/exec
Option 2: Change directories before your command
Alternatively, you can change to the root directory before running the command. adb shell (as of version 31.0.0-7110759) does not have the ability to set the working directory, but you can do this inside the shell by adding a cd before your rm. Note that the command must now be quoted to prevent your local shell from interpreting the list operator &&:
adb shell 'cd / && rm data/local/tmp/exec'
Note: The adb shell default working directory may vary by device or ROM. On my stock Pixel 3 it does in fact start at the root:
$ adb shell pwd
/

run linux bash script on adb shell [duplicate]

This question already has answers here:
Difference between sh and Bash
(11 answers)
Closed 1 year ago.
I'm trying to run linux shell script on adb shell. It's giving errors!
Here is the whole story:
I wrote a simple bash script hello.sh :
#!/bin/bash
function hello
{
echo "hello world!"
}
hello
running it as ./hello.sh produces the o/p
hello world!
Now I pushed the file to android device using
adb push hello.sh /data/folder_name
then ran following command to enter in adb shell
adb shell
In adb shell fired following commands
cd /data/folder_name
chmod 755 hello.sh
sh hello.sh
This is what I get on adb shell :
# sh hello.sh
sh hello.sh
function: not found
hello world!
hello: not found
#
What's happening here!
Or is there some different way to write function for adb shell script
I searched but didn't get proper solution
Please help.
Not sure about adb, but 'function' is not standard syntax. It is available in many shells, but the standard way to define a function is:
hello() { echo hello world; }
When invoked as sh, bash enters posix mode and it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.
The reserved word function is optional for bash, but I think is unknown to historical versions of sh.
Try to invoke the command as
bash /tmp/test.sh
You don't need to push the script to your phone - simply expand it in the shell itself like so and you save yourself time:
adb shell "$hello.sh"

adb command fail to execute if path contain spaces

I am trying to delete the file using adb command. But the file contain spaces. So adb command throws an error after reading half of the file name till space. Is there a way to overcome this issue. I am executing following adb command
When I execute
adb shell rm /sdcard/samsung_Nexus S_converter.xml
Error message: rm failed for /sdcard/samsung_Nexus, No such file or directory
How ever when I execute:
adb shell rm /sdcard/samsung_Nexus_S_converter.xml
File deletion is successful
I searched for solution for this, if there is any workaround. How ever I couldnt find any.
Since you are using command line, you need to know that spaces must be escaped by using (backslash before the special character like "space"), so, in your case this should work too:
adb shell rm /sdcard/samsung_Nexus\ S_converter.xml
Hope it helps!
Regards!
By me it wasn't enough to escape spaces with backslashes:
$ adb shell ls /storage/sdcard1/audio/Die\ Toten\ Hosen/
/storage/sdcard1/audio/Die: No such file or directory
Toten: No such file or directory
Hosen/: No such file or directory
For some reason I also had to surround the path with ' (single quotation):
$ adb shell ls '/storage/sdcard1/audio/Die\ Toten\ Hosen/'
03 - Boxed Set
04 - Compilations
05 - Live Albums
While surrounding without escaping didn't work:
$ adb shell ls '/storage/sdcard1/audio/Die Toten Hosen'
/storage/sdcard1/audio/Die: No such file or directory
Toten: No such file or directory
Hosen: No such file or directory
Did you tried escaping the space
adb shell rm /sdcard/samsung_Nexus\ S_converter.xml

Copying files in ADB shell with run-as

Is there a way to write a script that will copy files from an ADB shell using run-as?
The only way I know of to copy in the adb shell is using cat source > dest (edit: modern android versions have the cp command, which makes this question unnecessary), but I am only able to quote the greater-than sign one level deep - so my script can pass it to adb shell, but not to adb shell run-as.
For example, this works:
adb shell "cat source > dest"
But this does not:
adb shell run-as "cat source > dest"
Nor this:
adb shell "run-as cat source \> dest"
I even tried created a small script and uploading it to the device, but I can't seem to run the script from the adb shell - it tells me "permission denied". I can't chmod the script, either.
The reason I want to do this is to copy a file into an app's private storage area - specifically, I am using a script to modify shared preferences and put the modified preferences back. Only the app itself or root can write to the file I want, however.
The use case in this scenario is coping a file to a protected location on the device, not retrieving it; for retrieving, there are already good answers in this question.
The OP tried to combine the following 3 commands (that he had no problem executing one after another in the interactive shell session) into a single non-interactive command:
adb shell
run-as com.example.app
cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml
For simplicity let's start from within an interactive adb shell session. If we just try to combine the last two commands into a single line:
run-as com.example.app cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml
This would not work because of how shell redirection works - only the cat /sdcard/temp_prefs.xml part of the command would be run with com.example.app UID
Many people "know" to put the part of the command around redirection into quotes:
run-as com.example.app "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"
This does not work because the run-as command is not smart enough to parse the whole command. It expects an executable as the next parameter. The proper way to do it would be to use sh instead:
run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"
So can we just prepend adb shell to the command and be done with it? Not necessarily. By running the command from your PC you also add another local shell and its parser. Specific escape requirements would depend on your OS. In Linux or OSX (if your command does not already contain any ') it is easy to single-quote the whole command like so:
adb shell 'run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"'
But sometimes it is just easier to use an alternative solutions with (-out or less) quotes:
adb shell run-as com.example.app cp /sdcard/temp_prefs.xml shared_prefs/com.example.app_preferences.xml
Or if your device does not have the cp command:
adb shell run-as com.example.app dd if=/sdcard/temp_prefs.xml of=shared_prefs/com.example.app_preferences.xml
Also notice how I used shared_prefs/com.example.app_preferences.xml instead of full /data/data/com.example.app/shared_prefs/com.example.app_preferences.xml - normally inside of run-as command your current directory is the HOME dir of your package.
Following Chris Stratton's advice, the way I eventually got this to work was as follows (for copying shared preferences back to the device):
adb push shared_prefs.xml /sdcard/temp_prefs.xml
cat <<EOF | adb shell
run-as com.example.app
cat /sdcard/temp_prefs.xml > /data/data/com.example.app/shared_prefs/com.example.app_preferences.xml
exit
exit
EOF
Piping directly to adb shell run-as did not work, and I do not know why, but piping to adb shell does. The trick is to then call run-as from the interactive shell, and it continues to accept input from the pipe.
The HERE doc lets me easily embed the newlines to separate commands and in general just makes it readable; I did not have much luck with semicolons, but that might have been because of the way I was doing things. I believe it might work with other methods of piping multiple commands/newlines; I stopped the experiment once I finally got it to work.
The two exits are necessary to prevent a hanging shell (killable with CTRL-C); one for run-as, and the other for adb shell itself. Adb's shell doesn't respond to end-of-file very nicely, it seems.
you could just change the permission of the directory and then pull all the files out. but for me i was looking for just one shared preference file and i was able to get the data like this:
PACKAGE='com.mypackage.cool'
SHAREDPREF_FILE="${PACKAGE}_preferences.xml"
adb shell "run-as $PACKAGE cat /data/data/$PACKAGE/shared_prefs/$SHAREDPREF_FILE">$SHAREDPREF_FILE
now we have the data of the sharedpreference file stored in a file of the same name.
Using the latest adb (ADB v1.0.41 / Version 33.0.3) and a Play Store emulator image I experienced adb root not being granted. I also could not copy from /data/local/ or /storage/emulated/0/ due to not having permissions when run-as com.myapp.app
new_prefs_path="my_machine.xml"
config="$(cat $new_prefs_path)"
my_app_uri="com.myapp.app"
adb shell "run-as $my_app_uri sh -c 'echo \"$config\" > shared_prefs/on_android.xml'"
This fixes it for me as a bash script. It's made slightly more complicated by needing to be configurable for different apps and complex payloads.
We take a file (could be generated earlier in this script) and read it to a variable.
We then start shell, do run-as my app and run echo expanding the read file to a file in shared_prefs.

Applescript do shell script can't find Android ADB

I have a couple of shell scripts stored in the /Scripts folder of my AppleScript application.
I can access them by setting my base path
set basePath to POSIX path of ((path to me as text)) & "Contents/Resources/Scripts/"
But I'm only able to run the script if I call the Terminal app
-- This works
tell application "Terminal"
set currentTab to do script (basePath & "install_key.sh")
end tell
-- This does not work
do shell script basePath & "install_key.sh"
The error on do shell script complains about not being able to find adb (Android Debug Bridge)
FWIW, here is the shell script in question (install_key.sh)
#!/bin/bash
#Find script directory
DIR="$( cd "$( dirname "$0" )" && pwd )"
adb push $DIR"/key-dev.txt" /sdcard/ &&
adb shell mv /sdcard/key-dev.txt /sdcard/key.txt
Problem
If I understand correctly, your main issue is that your script cannot detect and hold the presence of a specific command located on a system.
Solution
I believe the following code will be effective in helping you achieve your goal. This applescript allows you to find whether ADB is stored on a system and store it's path in a variable. You can add the variable to your path and export as others have suggested or have a look at the export process in Apple's TN2065.
If ADB is not found on a system then users can receive a prompt telling them what actions to take (if that aligns with your use-case or you could begin the install sequence for ADB). To test the behavior of the script you can simply change the adp to some other (fake) command that does not exist on your system. I've added the path to the dialog so that you can see the do shell is passing the contents of the which command into a variable.
try
set adbPath to do shell script "which adb"
on error errStr number errorNumber
-- If our own error number, warn about bad data.
if the errorNumber is not equal to 0 then
display dialog "ADB is not loaded onto system. Please load ADB and run this app again"
return 0 -- Return the default value (0).
else
-- An unknown error occurred. Resignal, so the caller
-- can handle it, or AppleScript can display the number.
error errStr number errorNumber
end if
end try
if length of adbPath > 0 then display dialog "ADB found continue processing..." & adbPath
The structure defined in the TN2065 above is essentially:
$ VAR=something; export VAR $ osascript -e 'do shell script "echo $VAR"' something
You might also want to try the administrator option when calling the shell script:
do shell script "command" user name "me" password "mypassword" with administrator privileges
The Technical Note TN2065: do shell script in AppleScript is the key reference for this kind of issues.
when you use just a command name instead of a complete path, the shell
uses a list of directories (known as your PATH) to try and find the
complete path to the command. For security and portability reasons, do
shell script ignores the configuration files that an interactive shell
would read, so you don’t get the customizations you would have in
Terminal.
First: find the full path of adb
you have to open a Terminal and issue the following command:
$ which adb
suppose the response is:
/Users/ronda/projects/android/sdk/platform-tools/adb
this means that the path of adb is:
/Users/ronda/projects/android/sdk/platform-tools
, now we have several way to address the problem, for example follow one of these two options:
Option1: Fix the AppleScript
do shell script "PATH=${PATH}:/Users/ronda/projects/android/sdk/platform-tools; export PATH; echo $PATH; " & basePath & "install_key.sh"
Option2: Fix the shell script
for example you could specify full path to the adb command in your .sh this way:
#!/bin/bash
#Find script directory
DIR="$( cd "$( dirname "$0" )" && pwd )"
/Users/ronda/projects/android/sdk/platform-tools/adb push $DIR"/key-dev.txt" /sdcard/ &&
/Users/ronda/projects/android/sdk/platform-tools/adb shell mv /sdcard/key-dev.txt /sdcard/key.txt
The simplest solution would be running the same bash configuration as your terminal application. The main difference is that Terminal uses an interactive bash and do shell script command doesn't. To run an interactive shell you can simply execute a new one with option -i (stands for interactive). When an interactive shell is opened the ~/.bashrc file is used, while non-interactive shells don't use this file.
do shell script "bash -i <<<" & quoted form of (basePath & "install_key.sh" as text)
if you don't like that you can simply execute the bashrc file or read the path variable and set it in a do shell script.

Categories

Resources