如何在Android shell中复制和编辑文件?

Androidshell没有cp命令。 Androidshell也没有sedgrepvi 。 我没有可用的adb守护进程。 有mv命令,但如果源位于只读设备上,则拒绝工作。

  1. 如果我必须recursion地从只读设备复制一些目录,该怎么办?
  2. 如何更改文本文件中的一行(例如“PATH = / cache”为“PATH = / mnt / asec”)?

最常见的答案很简单:在APK中捆绑几个应用程序(busybox?)(假设你想在应用程序中使用它)。 据我所知,/数据分区没有安装noexec,即使你不想部署一个完整的APK,你可以修改ConnectBot源代码来构build一个包含一组命令行工具的APK。

对于命令行工具,我推荐使用crosstool-ng并build立一组静态链接的工具(与uClibc链接)。 他们可能很大,但他们肯定会工作。

要拷贝目录,看起来你可以使用adb pull <remote> <local>来从设备复制文件/目录,而adb push <local> <remote>拷贝文件/目录到设备。 或者,只要复制文件,您可以使用一个简单的技巧: cat source_file > dest_file 。 请注意,这不适用于用户不可访问的path。

要编辑文件,我还没有find一个简单的解决scheme,只是一些可能的解决方法。 试试看,你可以(设置后)使用它来编辑像busybox vi <filename> 。 纳米似乎也可以使用 。

你可以做到没有root权限:

 cat srcfile > /sdcard/dstfile 

您可以使用cat > filename来使用标准input来写入文件。 最后你必须把EOF CTRL+D

另外,如果目标只是访问手机上的文件。 有一个可从Eclipse DDMS透视图访问的文件资源pipe理器。 它可以让你从设备上复制文件。 所以你总是可以得到文件,修改它并把它放回到设备上。 当然,它只能访问未被读保护的文件。

如果你没有看到文件浏览器,从DDMS的angular度来看,进入“窗口” – >“显示视图” – >“文件资源pipe理器”。

由于我的设备上的权限策略有点偏执(不能adb pull应用程序数据),我写了一个脚本recursion复制文件。

注意:这个recursion的文件/文件夹复制脚本是为Androiddevise的!

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 

在这里,我提供了Android的轻量级find源,因为在某些设备上这个工具丢失了。 如果在设备上定义,则可以使用find代替myfind

安装:

 $ adb push copy-r /sdcard/ 

adb shell运行(rooted):

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

要么

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

(上面的散列#su提示符,而.是使shell运行指定文件的命令,与source几乎相同)。

复制后,我可以adb pull从SD adb pull文件。

写文件到应用程序目录是棘手的,我试图设置files及其子目录的权限,这是行不通的(嗯,它允许我读,但不写,这是奇怪的),所以我不得不做:

  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(); } 

在应用程序的onCreate()中

PS以防万一有人需要代码解除应用程序的目录,以启用非根的手机上的adb shell访问,

  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); } } 

虽然由于某种未知的原因,我可以读,但不能写。

如果你有根访问安装busybox( 谷歌的说明 )。

我可以build议只在你的设备上安装Terminal-ide , 在游戏市场上有售。 它的免费,不需要root和提供方便的* nix环境,如cp,find,du,mc等许多以二进制forms安装的实用程序。