脚本将使用adb

时间:2019-06-20 17:51:07

标签: android bash sh adb

故事

我用手机摄像头拍照并录制视频,并将所有视频保存在sdcard中。我会定期将它们备份到我的PC上,因此我会将这些相机照片保留在PC存储上与手机存储保持同步。

多年来,我一直通过以下方式将手机摄像头照片备份到PC:

  1. 将手机插入PC并允许访问手机数据
  2. 浏览SDCard→DCIM→相机
  3. 等待几分钟,系统将加载所有照片列表
  4. 仅复制几张尚未备份的最新照片

我认为等待几分钟以加载所有照片是不必要的拖动操作,因此我下载了adb platform tools。我已将文件夹bin添加到我的Path环境变量(即%USERPROFILE%\Tools\adb-platform-tools_r28.0.3)中,以便可以无缝使用adb而不必每次都写其完整路径。

脚本

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

# 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)时,除adb pull循环中的while命令外,其他所有程序都运行顺利。 它出现以下错误

': 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 Bash窗口的大小时,其中的一些文本变得有些混乱。这是实际的错误文本:

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中手动执行失败的命令时,它会成功显示以下输出

$ 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 Bash会将/解释为其自己的根目录( C:\ Program Files \ Git < / em>)。
  • 我已经echo删除了脚本中的所有变量,并获得了所有正确的路径,这些路径本来可以通过手动方法来工作。

camera-ls.txt文件内容

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

2 个答案:

答案 0 :(得分:0)

问题出在 Windows行定界符

轻松修复

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

IFS=$'\r\n'
while read filename; do
  if [ -z "$filename" ]; then continue; fi
  adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"

说明

我尝试将整个while循环插入控制台,但由于相同的错误而失败:

$ 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作为换行符,这意味着回车+换行符(CR + LF),因此某些文本必须被覆盖。

这是因为$filename变量中存储的值损坏。

这是脚本的循环:

while read filename; do
  if [ -z "$filename" ]; then continue; fi
  adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"

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

exampleFilename.jpg\r\n

它会将换行符号误解为文件名的一部分,因此adb pull尝试读取名称中带有这些空格的文件,但失败了,并另外写入了损坏的输出。

答案 1 :(得分:0)

Windows批处理脚本

这是一个.bat脚本,可由 Windows命令提示符 Windows PowerShell 运行。不需要Git Bash。

:: 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上安装Windows的adb