【问题标题】:How to copy and edit files in Android shell?如何在 Android shell 中复制和编辑文件?
【发布时间】:2011-06-10 12:11:44
【问题描述】:

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

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

【问题讨论】:

  • 提供的任何解决方案对您有用吗?
  • @MEGA:正如我所说,没有安装 adb。我可以使用“cat src > dst”命令进行复制,但我不知道如何递归?
  • 我不明白。要访问 shell,请键入 ./adb shell。如果您说您没有可用的adb,您如何访问shell?
  • @MEGA:我有单独的串行终端(通过 COM 端口)
  • 好的,我明白了。根据我的发现,pullpush 是递归的。 Check out here.

标签: android linux shell android-ndk sh


【解决方案1】:

要复制目录,如果你想从设备复制文件/目录,你似乎可以使用adb pull <remote> <local>,并使用adb push <local> <remote> 将文件/目录复制到设备。或者,只是为了复制文件,您可以使用一个简单的技巧:cat source_file > dest_file。请注意,这不适用于用户无法访问的路径。

要编辑文件,我还没有找到简单的解决方案,只是一些可能的解决方法。试试this,看来你可以(在设置之后)用它来编辑像busybox vi <filename> 这样的文件。 Nano 好像也是possible to use

【讨论】:

  • 很遗憾,adb pull/adb push 不适用于用户无法访问的路径。
  • 刚刚帮助我从无法访问的 SD 卡分区中恢复了 500 多张照片和视频。谢谢:)
【解决方案2】:

你可以在没有root权限的情况下这样做:

cat srcfile > /mnt/sdcard/dstfile

【讨论】:

  • 它也适用于二进制文件吗?还是只适用于 TEXT 文件?
  • 谢谢!你节省了我的时间
  • 没有。你不能复制没有root权限的文件。我正在尝试将 data/data/my.application.android/databases/MYDATABASE.db 复制到 sdcard 但我收到消息 Permission denied
  • @Orientos 在您的情况下,没有 root 就无法访问源文件。您正在尝试复制应用程序私有文件。最初的问题假设源文件是可读的。如果它是您的应用程序并且正在调试中,您可以使用以下命令: adb -d shell "run-as my.application.android cat my.application.android/databases/MYDATABASE.db" > /mnt/sdcard/MYDATABASE.db "
【解决方案3】:

对此最常见的答案很简单:将几个应用程序(busybox?)与您的 APK 捆绑在一起(假设您想在应用程序中使用它)。据我所知,/data 分区没有挂载 noexec,即使您不想部署成熟的 APK,也可以修改 ConnectBot 源以构建包含一组命令行工具的 APK。

对于命令行工具,我建议使用 crosstool-ng 并构建一组静态链接工具(链接到 uClibc)。它们可能很大,但它们肯定会起作用。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      如果目标只是访问手机上的文件。有一个可以从 Eclipse DDMS 透视图访问的文件资源管理器。它使您可以将文件从设备复制到设备。因此,您始终可以获取文件、对其进行修改并将其放回设备上。当然它只允许访问没有读保护的文件。

      如果您没有看到文件资源管理器,从 DDMS 的角度来看,请进入“窗口”->“显示视图”->“文件资源管理器”。

      【讨论】:

        【解决方案6】:

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

        注意:此递归文件/文件夹复制脚本适用于 Android!

        复制-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,则可以使用find,而不是myfind

        安装:

        $ adb push copy-r /sdcard/
        

        adb shell (root) 内运行:

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

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

        (上面的哈希#su提示符,而.是导致shell运行指定文件的命令,几乎和source一样)。

        复制后,我可以adb pull sd卡中的文件。

        将文件写入 app 目录比较棘手,我尝试在 files 及其子目录上设置 r/w 权限,但没有成功(嗯,它允许我读取,但不能写入,这很奇怪),所以我不得不这样做:

                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 以防万一有人需要代码来取消保护应用程序的目录以在非 root 手机上启用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);
                }
            }
        

        虽然不知什么原因我能读但不能写。

        【讨论】:

          【解决方案7】:

          如果您有 root 访问权限,请安装 busybox (google for instructions)。

          【讨论】:

          • 谢谢!对于现在遇到这个问题的人来说,现在有一个非 root 安装程序可用,它在紧急情况下只用我的平板电脑给了我 grep 等 :)
          • busybox 已经在我的一加 3t 上,出于某种原因它被称为“盒子”。
          【解决方案8】:

          Android 支持 dd 命令。

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

          【讨论】:

            【解决方案9】:

            我可以建议在你的设备上安装Terminal-ide 可用in play market。它是免费的,不需要root,并提供方便的*nix环境,如cp、find、du、mc和许多其他一键安装以二进制形式安装的实用程序。

            【讨论】:

              【解决方案10】:

              我尝试在 mac 上关注。

              1. 启动终端并移动到 adb 所在的文件夹。在 Mac 上,通常是 /Library/Android/sdk/platform-tools
              2. 现在打开开发者模式连接设备,并使用命令./adb status 检查设备状态。 "./" 应以“adb”为前缀。
              3. 现在我们可能需要知道设备中的目标文件夹位置。您可以通过adb shell 进行检查。使用命令./adb shell 进入 adb shell。现在我们可以使用 shell 访问设备的文件夹了。
              4. 您可以使用命令ls -la 列出所有文件夹。
              5. 通常我们会在我们的设备中找到一个文件夹/sdcard。(您可以在此处选择任何文件夹。)假设我的目标是/sdcard/3233-3453/DCIM/Videos,源是~/Documents/Videos/film.mp4
              6. 现在我们可以退出 adb shell 以访问我们机器上的文件系统。命令:./adb exit
              7. 现在./adb push [source location] [destination location]
                ./adb push ~/Documents/Videos/film.mp4 /sdcard/3233-3453/DCIM/Videos
              8. 瞧。

              【讨论】:

                【解决方案11】:

                如果您只想附加到文件,例如要在配置文件中添加一些行,内置的 shell 命令就足够了:

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

                在上面,将/path/to/file 替换为您要编辑的文件。您需要对该文件具有写入权限,这意味着如果您正在编辑系统文件,则需要 root 访问权限。其次,将some text to appenda second line of text to append 替换为您要添加的行。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2019-10-22
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-06-27
                  • 2015-06-11
                  • 1970-01-01
                  • 2011-05-02
                  相关资源
                  最近更新 更多