首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用adb从手机摄像机传输照片的脚本

使用adb从手机摄像机传输照片的脚本
EN

Stack Overflow用户
提问于 2019-06-20 17:51:07
回答 3查看 2.4K关注 0票数 4

故事

我用我的手机相机拍摄照片和录像,并将它们全部保存在我的内部存储器/sdcard中。我定期备份他们在我的个人电脑,所以我保持这些相机照片在个人电脑存储与手机存储同步。

多年来,我一直以以下方式将手机相机照片备份到我的PC上:

  1. 将电话插入PC并允许访问电话数据。
  2. 浏览手机存储→DCIM→摄像头
  3. 等了几分钟系统才能加载所有照片的列表
  4. 只复制几张尚未备份的最新照片

我认为等待几分钟所有照片加载是不必要的拖放,所以我下载了亚行平台工具。我将文件夹bin添加到我的Path环境变量(即%USERPROFILE%\Tools\adb-platform-tools_r28.0.3)中,这样我就可以无缝地使用adb,而不是每次都编写完整的路径。

脚本

我为吉特巴什为Windows编写了以下脚本。如果您更改$userprofile变量,它也与Unix兼容。从本质上讲,脚本将两个日期之间的相机照片从电话存储到PC

代码语言:javascript
复制
# Attach device and start deamon process
adb devices

# Initialize needed variables
userprofile=$(echo "$USERPROFILE" | tr "\\" "/") # Windows adjustments

srcFolder="//storage/06CB-C9CE/DCIM/Camera"    # Remote folder
dstFolder="$userprofile/Desktop/CameraPhotos"  # Local folder
lsFile="$dstFolder/camera-ls.txt"
filenameRegex="2019061[5-9]_.*"  # Date from 20190615 to 20190619

# Create dst folder if it doesn't exist
mkdir -p "$dstFolder"

# 1. List contents from src folder
# 2. Filter out file names matching regex
# 3. Write these file names line by line into a ls file
adb shell ls "$srcFolder" | grep -E "$filenameRegex" > "$lsFile"

# Pull files listed in ls file from src to dst folder
while read filename; do
  if [ -z "$filename" ]; then continue; fi
  adb pull "$srcFolder/$filename" "$dstFolder" # adb: error: ...
done < "$lsFile"

# Clean up
rm "$lsFile"

# Inform the user
echo "Done pulling files to $dstFolder"

问题所在

当我运行脚本(bash adb-pull-camera-photos.sh)时,除了while-loop中的adb pull命令之外,一切都运行顺利。给出了以下错误

代码语言:javascript
复制
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_204522.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190619_225739.jpg

我不知道为什么输出坏了。有时候,当我调整Git窗口的大小时,有些文本会乱七八糟。这是实际的错误文本:

代码语言:javascript
复制
adb: error: failed to stat remote object '//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg': No such file or directory
adb: error: failed to stat remote object '//storage/06CB-C9CE/DCIM/Camera/20190618_204522.jpg': No such file or directory
adb: error: failed to stat remote object '//storage/06CB-C9CE/DCIM/Camera/20190619_225739.jpg': No such file or directory

我确信这些文件存在于电话中指定的目录中。当我在bash中手动执行失败的命令时,使用以下输出成功

代码语言:javascript
复制
$ adb pull "//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg" "C:/Users/User/Desktop/CameraPhotos/"
//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg: 1 file pulled. 15.4 MB/s (1854453 bytes in 0.115s)

问题是

我不知道剧本有什么问题。我认为Windows系统可能会引起混乱,因为我看不出为什么相同的代码在手动输入时工作,但在脚本中运行时却不能工作。如何修复此错误?

更多信息

  • 请注意,我必须在Windows绝对路径的开头使用//,因为Git会将/解释为自己的根目录(C:\Program \Git)。
  • 我已经对脚本中的所有变量进行了echo编辑,并获得了所有其他通过手动方法工作的正确路径。

照相机-ls.txt文件内容

代码语言:javascript
复制
20190618_124656.jpg
20190618_204522.jpg
20190619_225739.jpg

附加问题

  1. 是否可以不使用其名称而导航到外部sdcard?我不得不使用/storage/06CB-C9CE/,因为/sdcard/导航到内部存储。
  2. 为什么tr "\\" "/"给我这个错误:tr: warning: an unescaped backslash at end of string is not portable
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-06-20 18:09:53

问题在于窗口行分隔符

易修

只需在循环上方添加IFS=$'\r\n',以便read命令知道实际的行分隔符。

代码语言:javascript
复制
IFS=$'\r\n'
while read filename; do
  if [ -z "$filename" ]; then continue; fi
  adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"

解释

我尝试将整个while-loop插入控制台,但失败时也出现了同样的错误:

代码语言:javascript
复制
$ bash adb-pull-camera-photos.sh
List of devices attached
9889db343047534336      device

tr: warning: an unescaped backslash at end of string is not portable
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_124656.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190618_204522.jpg
': No such file or directoryemote object '//storage/06CB-C9CE/DCIM/Camera/20190619_225739.jpg
Done pulling files to C:/Users/User/Desktop/CameraPhotos

这一次,我开始研究为什么输出会中断,。我记得windows使用\r\n作为换行符,这意味着传输返回+ Line,(CR+LF),所以一定有一些文本被覆盖了。

这是因为存储在$filename变量中的值被破坏了。

这是脚本中的循环:

代码语言:javascript
复制
while read filename; do
  if [ -z "$filename" ]; then continue; fi
  adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"

由于while-loop的每次迭代都以以下形式从$lsFile读取一行:

代码语言:javascript
复制
exampleFilename.jpg\r\n

它将换行符错误地解释为文件名的一部分,所以亚行拉试着用这些空格读取文件,但是失败了,而且它还写入了一个坏的输出。

票数 0
EN

Stack Overflow用户

发布于 2019-06-20 19:47:04

Windows批处理脚本

下面是一个.bat脚本,可以由Windows命令提示符Windows PowerShell运行。不需要吉特巴什。

代码语言:javascript
复制
:: Start deamon of the device attached
adb devices

:: Pull camera files starting from date
set srcFolder=/storage/06CB-C9CE/DCIM/Camera
set dstFolder=%USERPROFILE%\Desktop\CameraPhotos
set lsFile=%USERPROFILE%\Desktop\CameraPhotos\camera-ls.txt
set dateRegex=2019061[5-9]_.*

mkdir %dstFolder%
adb shell ls %srcFolder% | adb shell grep %dateRegex% > %lsFile%
for /F "tokens=*" %%A in (%lsFile%) do adb pull %srcFolder%/%%A %dstFolder%
del %lsFile%
echo Done pulling files to %dstFolder%
  • 只要编辑srcFolder指向你的手机相机文件夹,
  • 将模式插入dateRegex以匹配日期间隔和
  • 将其保存为具有.bat扩展名的文件,即:adb-pull-camera-photos.bat
  • 双击该文件,它将把过滤过的照片拖到桌面上的CameraPhotos文件夹中.

请记住,您仍然需要在您的PC上有https://developer.android.com/studio/releases/platform-tools.html的Windows。

票数 1
EN

Stack Overflow用户

发布于 2021-12-14 16:55:51

亚行摄影同步

这可能不是答案,但对于其他寻找android照片/文件备份解决方案的人来说可能是有用的。

我在我的Windows上使用这个脚本和git。这可以很容易地用于Linux。长备份过程的一个常见问题是它可能会被中断,您可能必须从一开始就重新启动整个复制过程。

这个脚本把你从麻烦中救了出来。您可以在中间重新启动脚本或中断,但它将从它离开的点恢复复制操作。

只需更改重新文件夹=> android文件夹,=>本地文件夹

代码语言:javascript
复制
#!/bin/sh

rfolder=sdcard/DCIM/Camera
lfolder=/f/mylocal/s8-backup/Camera

adb shell ls "$rfolder" > android.files

ls -1 "$lfolder" > local.files

rm -f update.files
touch update.files

while IFS=  read -r q; do
  # Remove non-printable characters (are not visible on console)
  l=$(echo ${q} | sed 's/[^[:print:]]//')
  # Populate files to update
  if ! grep -q "$l" local.files; then         
    echo "$l" >> update.files
  fi  
done < android.files

script_dir=$(pwd)
cd $lfolder

while IFS=  read -r q; do
  # Remove non-printable characters (are not visible on console)
  l=$(echo ${q} | sed 's/[^[:print:]]//')
  echo "Get file: $l"
  adb pull "$rfolder/$l"
done < "${script_dir}"/update.files
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56691427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档