72

The Android shell does not have the cp command. Android shell also has no sed or grep or vi. I have no adb daemon available. There is mv command but it rejects to work if source is on a read-only device.

  1. What to do if I have to copy some directories from read-only device recursively?
  2. How to change a line in a text file (e.g. "PATH=/cache" to be "PATH=/mnt/asec") ?
6
  • Did any of the solutions provided work for you? Commented Feb 2, 2011 at 18:47
  • @MEGA: as I said, there is no adb installed. I can copy using "cat src > dst" command, but I dont know how to make it recursively? Commented Feb 3, 2011 at 9:00
  • I don't get it. To access the shell, you type ./adb shell. If you are saying you have no adb available, how can you access the shell? Commented Feb 3, 2011 at 10:27
  • @MEGA: I have separate serial terminal (through COM port) Commented Feb 3, 2011 at 10:37
  • Ok, I get it. From what I found, pull and push are recursive. Check out here. Commented Feb 3, 2011 at 10:55

11 Answers 11

98
+25

To copy dirs, it seems you can use adb pull <remote> <local> if you want to copy file/dir from device, and adb push <local> <remote> to copy file/dir to device. Alternatively, just to copy a file, you can use a simple trick: cat source_file > dest_file. Note that this does not work for user-inaccessible paths.

To edit files, I have not found a simple solution, just some possible workarounds. Try this, it seems you can (after the setup) use it to edit files like busybox vi <filename>. Nano seems to be possible to use too.

Sign up to request clarification or add additional context in comments.

3 Comments

Unfortunately, adb pull/adb push won't work with user-inaccessable paths.
Just helped me recover 500+ photos and videos from an inaccessible SD card partition. Thanks :)
12 years later and I just used adb pull to copy a system file from an old version of Android to a new one. Thanks for this!
32

You can do it without root permissions:

cat srcfile > /mnt/sdcard/dstfile 

3 Comments

does it work for binary files, too? or it just works for TEXT files?
no. you can't copy the file without root permissions. i am trying to copy data/data/my.application.android/databases/MYDATABASE.db to sdcard but im getting the message Permission denied
@Orientos in your case the source file is not acessible without root. You are trying to copy an application private file. The original question assumed the source file was readable. If it is your application and is in debug you can use the following: adb -d shell "run-as my.application.android cat my.application.android/databases/MYDATABASE.db" > /mnt/sdcard/MYDATABASE.db"
17

The most common answer to that is simple: Bundle few apps (busybox?) with your APK (assuming you want to use it within an application). As far as I know, the /data partition is not mounted noexec, and even if you don't want to deploy a fully-fledged APK, you could modify ConnectBot sources to build an APK with a set of command line tools included.

For command line tools, I recommend using crosstool-ng and building a set of statically-linked tools (linked against uClibc). They might be big, but they'll definitely work.

Comments

9

You can use cat > filename to use standart input to write to the file. At the end you have to put EOF CTRL+D.

Comments

5

Since the permission policy on my device is a bit paranoid (cannot adb pull application data), I wrote a script to copy files recursively.

Note: this recursive file/folder copy script is intended for Android!

copy-r:

#! /system/bin/sh src="$1" dst="$2" dir0=`pwd` myfind() { local fpath=$1 if [ -e "$fpath" ] then echo $fpath if [ -d "$fpath" ] then for fn in $fpath/* do myfind $fn done fi else : echo "$fpath not found" fi } if [ ! -z "$dst" ] then if [ -d "$src" ] then echo 'the source is a directory' mkdir -p $dst if [[ "$dst" = /* ]] then : # Absolute path else # Relative path dst=`pwd`/$dst fi cd $src echo "COPYING files and directories from `pwd`" for fn in $(myfind .) do if [ -d $fn ] then echo "DIR $dst/$fn" mkdir -p $dst/$fn else echo "FILE $dst/$fn" cat $fn >$dst/$fn fi done echo "DONE" cd $dir0 elif [ -f "$src" ] then echo 'the source is a file' srcn="${src##*/}" if [ -z "$srcn" ] then srcn="$src" fi if [[ "$dst" = */ ]] then mkdir -p $dst echo "copying $src" '->' "$dst/$srcn" cat $src >$dst/$srcn elif [ -d "$dst" ] then echo "copying $src" '->' "$dst/$srcn" cat $src >$dst/$srcn else dstdir=${dst%/*} if [ ! -z "$dstdir" ] then mkdir -p $dstdir fi echo "copying $src" '->' "$dst" cat $src >$dst fi else echo "$src is neither a file nor a directory" fi else echo "Use: copy-r src-dir dst-dir" echo "Use: copy-r src-file existing-dst-dir" echo "Use: copy-r src-file dst-dir/" echo "Use: copy-r src-file dst-file" fi 

Here I provide the source of a lightweight find for Android because on some devices this utility is missing. Instead of myfind one can use find, if it is defined on the device.

Installation:

$ adb push copy-r /sdcard/ 

Running within adb shell (rooted):

# . /sdcard/copy-r files/ /sdcard/files3 

or

# source /sdcard/copy-r files/ /sdcard/files3 

(The hash # above is the su prompt, while . is the command that causes the shell to run the specified file, almost the same as source).

After copying, I can adb pull the files from the sd-card.

Writing files to the app directory was trickier, I tried to set r/w permissions on files and its subdirectories, it did not work (well, it allowed me to read, but not write, which is strange), so I had to do:

 String[] cmdline = { "sh", "-c", "source /sdcard/copy-r /sdcard/files4 /data/data/com.example.myapp/files" }; try { Runtime.getRuntime().exec(cmdline); } catch (IOException e) { e.printStackTrace(); } 

in the application's onCreate().

PS just in case someone needs the code to unprotect application's directories to enable adb shell access on a non-rooted phone,

 setRW(appContext.getFilesDir().getParentFile()); public static void setRW(File... files) { for (File file : files) { if (file.isDirectory()) { setRW(file.listFiles()); // Calls same method again. } else { } file.setReadable(true, false); file.setWritable(true, false); } } 

although for some unknown reason I could read but not write.

Comments

4

Also if the goal is only to access the files on the phone. There is a File Explorer that is accessible from the Eclipse DDMS perspective. It lets you copy file from and to the device. So you can always get the file, modify it and put it back on the device. Of course it enables to access only the files that are not read protected.

If you don't see the File Explorer, from the DDMS perspective, go in "Window" -> "Show View" -> "File Explorer".

Comments

3

Android supports the dd command.

dd if=/path/file of=/path/file 

Comments

2

If you have root access install busybox (google for instructions).

2 Comments

Thanks! And for anyone stumbling across this now, there's now a non-root installer available, which gave me grep etc in an emergency with only my tablet :)
busybox is already there on my one plus 3t, its called 'box' for some reason.
1

I could suggest just install Terminal-ide on you device which available in play market. Its free, does not require root and provide convenient *nix environment like cp, find, du, mc and many other utilities which installed in binary form by one button tap.

Comments

0

I tried following on mac.

  1. Launch Terminal and move to folder where adb is located. On Mac, usually at /Library/Android/sdk/platform-tools.
  2. Connect device now with developer mode on and check device status with command ./adb status. "./" is to be prefixed with "adb".
  3. Now we may need know destination folder location in our device. You can check this with adb shell. Use command ./adb shell to enter an adb shell. Now we have access to device's folder using shell.
  4. You may list out all folders using command ls -la.
  5. Usually we find a folder /sdcard within our device.(You can choose any folder here.) Suppose my destination is /sdcard/3233-3453/DCIM/Videos and source is ~/Documents/Videos/film.mp4
  6. Now we can exit adb shell to access filesystem on our machine. Command: ./adb exit
  7. Now ./adb push [source location] [destination location]
    i.e. ./adb push ~/Documents/Videos/film.mp4 /sdcard/3233-3453/DCIM/Videos
  8. Voila.

Comments

0

If you just want to append to a file, e.g. to add some lines to a configuration file, inbuilt shell commands are enough:

adb shell cat >> /path/to/file <<EOF some text to append a second line of text to append EOF exit 

In the above, replace /path/to/file with the file you want to edit. You'll need to have write permission on the file, which implies root access if you're editing a system file. Secondly, replace some text to append and a second line of text to append with the lines you want to add.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.