71

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") ?
psihodelia
  • 29,566
  • 35
  • 108
  • 157
  • Did any of the solutions provided work for you? – gnclmorais Feb 02 '11 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? – psihodelia Feb 03 '11 at 09: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? – gnclmorais Feb 03 '11 at 10:27
  • @MEGA: I have separate serial terminal (through COM port) – psihodelia Feb 03 '11 at 10:37
  • Ok, I get it. From what I found, `pull` and `push` are recursive. [Check out here.](http://developer.android.com/guide/developing/tools/adb.html#copyfiles) – gnclmorais Feb 03 '11 at 10:55
  • I want to to copy file from one directory to another directory using native c code. so how can i achieve this? i also Installed busy-box – user1089679 Mar 21 '12 at 16:55

11 Answers11

97

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.

Community
  • 1
  • 1
gnclmorais
  • 4,897
  • 5
  • 30
  • 41
  • 18
    Unfortunately, `adb pull`/`adb push` won't work with user-inaccessable paths. – ulidtko Sep 13 '11 at 21:31
  • 2
    Just helped me recover 500+ photos and videos from an inaccessible SD card partition. Thanks :) – Phantomwhale Aug 13 '12 at 12:37
  • 1
    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! – lchras Aug 17 '23 at 20:36
32

You can do it without root permissions:

cat srcfile > /mnt/sdcard/dstfile
Viriatvs
  • 494
  • 5
  • 7
  • does it work for binary files, too? or it just works for TEXT files? – VSB Jun 12 '13 at 05:38
  • 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 Aug 08 '18 at 07:42
  • 1
    @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" – Viriatvs Aug 09 '18 at 16:06
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.

p_l
  • 1,179
  • 8
  • 17
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.

kubo
  • 492
  • 7
  • 19
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.

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127
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".

jmbouffard
  • 1,581
  • 1
  • 15
  • 22
2

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

Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
  • 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 :) – herdingofthecats Feb 08 '15 at 04:26
  • busybox is already there on my one plus 3t, its called 'box' for some reason. – Amias Apr 08 '17 at 14:48
2

Android supports the dd command.

dd if=/path/file of=/path/file
Bsquare ℬℬ
  • 4,423
  • 11
  • 24
  • 44
jrc
  • 21
  • 1
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.

Hubbitus
  • 5,161
  • 3
  • 41
  • 47
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.
Jose
  • 2,479
  • 1
  • 20
  • 17
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.

bleater
  • 5,098
  • 50
  • 48