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
/
Related
My working directory is /data/local/tmp.
I create and push a shell script file here named get_meminfo.sh.
The core function of it is record the RSS usage and save as a log file, like this: rss_res >> rss.log
But now I find a problem: I can run the script file when I enter the android shell, like ./get_meminfo.sh, and I can see the log file created in the path.
However when I try to run it from adb, like: adb shell /data/local/tmp/get_meminfo.sh, it will get an error: can't create file, read-only file system!
It seems that you do not quite understand the concept of the current working dirtectory.
The rss_res >> rss.log command creates rss.log in the current working dirtectory. Which in case of the following command sequence is /data/local/tmp:
adb shell
cd /data/local/tmp
./get_meminfo.sh
So rss.log gets created in /data/local/tmp which is world writable.
But in case of adb shell /data/local/tmp/get_meminfo.sh the cwd is the / root folder. Which is not writable and the command fails.
The easiest way to mitigate that is to use the absolute path for your log file inside of your script like this rss_res >> /data/local/tmp/rss.log
1. Added adb path to ~/.bash_profile
export PATH="/Users/myname/Library/Android/sdk/platform-tools:$PATH"
2. Logged in to emulator
adb -s emulator-5554 shell
3. changed permission of the app folder and parent folder
chmod 777 /data/data/com.me.myproject
chmod 777 /data/data
4. Still can not get stuff from outside. Why?
adb -s emulator-5554 pull /data/data/com.me.myproject
I had the same problem and I did this:
adb shell
run-as com.yourPackageName (not rooted device)
cp 'database/file_you_want.db' '/sdcard/file_you_want.db'
exit
exit (now you will be back to main terminal window)
adb pull /sdcard/xx.db
That's because your debugging Android device is not rooted.
If you have a physical rooted device or have an emulated device, try executing this before, to restart ADB in root mode. Then any command should work:
adb root
The reason is the file you wanted to copy needs root permission. It's better to copy the file to /mnt/sdcard/ where you have a right to interact with.
cp <file> /mnt/sdcard/
adb pull /mnt/sdcard/<file>
connect mobile to laptop then open adb console
a). cp msg-store.db /mnt/sdcard/ ==>inside /data/data/packagename/databases/
b). adb pull /mnt/sdcard/msg-store.db/ ===>This will stored in local computer.
prefixing the remote path with ./ or removing the leading / makes the whole difference for me ??? I guess because the system folder must be relative to root's home?
Darn it, those stupid Linux folks wasted my time again. I admit my whole life is about relative paths but this one got me good.
Make sure you use \ for your target file, stupid Bill G. also decided to go backwards with his slashes and that created a whole mess. :)
PS. What's even weirder both files in my examples were pulled (copied) to the BASH shell current folder NOT c:\
That's stupid or what :)
FAILS
adb -s 192.168.1.120:5555 pull /system/media/bootanimation.zip c:\boot1.zip
SUCCEEDS
adb -s 192.168.1.120:5555 pull ./system/media/bootanimation.zip c:\boot1.zip
SUCCEEDS
adb -s 192.168.1.120:5555 pull system/media/bootanimation.zip c:\boot1.zip
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
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.
I wish to send an adb shell command to an Android device that pipes output from 1 command to other command, but when I try to do that, only the 1st command is executed on the device, and the 2nd one is executed on the host machine. Here's what I tried:
adb shell command1 | command2
command1 is executed on the device, and command2 on the host machine.
How can I get this to work properly?
Thanks!
You could use something like this:
adb shell "command1 | command2"
One way is to create a shell script containing the commands you want and then run the shell script.
Since the Android root filesystem is not writeable at run time (usually, unless you have rooted your device and remount it), you can copy the file to the removable (or emulated) storage, for example /sdcard.
Then run the script using the command adb shell sh /sdcard/your-script-name. Because each script runs in its own subshell, both of your commands will be executed in the same shell on the device (you can confirm it with ps).
adb shell "command1 && command2"
example:
Recursive listing of all files under /system/lib that contain 'foo':
adb shell "cd /system/lib&&ls -lR .|grep -i foo"
The important thing is the double quotes and the double ampersand.
The only thing is that you cannot use it for input as well, meaning that running an executable that requires stdin using one-liner wouldn't work as it requires user intervention.