[英]Script that will transfer photos from phone camera using adb
I take photos and record videos with my phone camera and keep all of them on my internal storage/sdcard.我用手机摄像头拍照和录制视频,并将所有这些都保存在我的内部存储/sdcard 中。 I periodically back them up on my PC, so I keep these camera photos on PC storage in sync with phone storage.我会定期将它们备份到我的 PC 上,因此我将这些相机照片保存在 PC 存储中与手机存储同步。
For years, I've been backing up my phone camera photos to my PC in the following way:多年来,我一直通过以下方式将手机相机照片备份到我的 PC:
I figured that waiting several minutes for all photos to load is an unnecessary drag so I downloaded adb platform tools .我认为等待几分钟加载所有照片是不必要的拖累,所以我下载了adb 平台工具。 I've added the folder bin to my Path
environment variable (ie %USERPROFILE%\\Tools\\adb-platform-tools_r28.0.3
) so that I can seamlessly use adb
and not write its full path each time.我已将文件夹 bin 添加到我的Path
环境变量(即%USERPROFILE%\\Tools\\adb-platform-tools_r28.0.3
),以便我可以无缝地使用adb
而不是每次都写出它的完整路径。
I wrote the following script for Git Bash for Windows.我为 Windows 版Git Bash编写了以下脚本。 It is also compatible with Unix if you change the $userprofile
variable.如果您更改$userprofile
变量,它也与 Unix 兼容。 Essentially, the script pulls camera photos between two dates from phone storage to PC .本质上,该脚本将两个日期之间的相机照片从手机存储中提取到 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"
When I run the script ( bash adb-pull-camera-photos.sh
), everything runs smoothly except for the adb pull
command in the while
-loop.当我运行该脚本( bash adb-pull-camera-photos.sh
),一切运行顺利除adb pull
的命令while
-loop。 It gives the following error :它给出了以下错误:
': 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
I am not sure why the output is broken.我不确定为什么输出被破坏了。 Sometimes when I resize the Git Bash window some of the text goes haywire.有时当我调整 Git Bash 窗口的大小时,一些文本会变得混乱。 This is the actual error text:这是实际的错误文本:
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
I am sure that these files exist in the specified directory on the phone.我确定这些文件存在于手机上的指定目录中。 When I manually execute the failing command in bash, it succeeds with the following output :当我在 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)
I can't figure out what's wrong with the script.我无法弄清楚脚本有什么问题。 I thought the Windows system might be causing a commotion, because I don't see the reason why the same code works when entered manually, but doesn't work when run in a script.我认为Windows系统可能会引起骚动,因为我不明白为什么手动输入时相同的代码有效,但在脚本中运行时不起作用。 How do I fix this error?我该如何解决这个错误?
//
in the beginning of an absolute path on Windows because Git Bash would interpret /
as its own root directory ( C:\\Program Files\\Git ).请注意,我必须在 Windows 上绝对路径的开头使用//
因为 Git Bash 会将/
解释为它自己的根目录( C:\\Program Files\\Git )。echo
ed all variables inside the script and got all the correct paths that otherwise work via manual method.我已经echo
了脚本中的所有变量,并获得了所有正确的路径,否则这些路径可以通过手动方法工作。20190618_124656.jpg
20190618_204522.jpg
20190619_225739.jpg
/storage/06CB-C9CE/
because /sdcard/
navigates to internal storage.我不得不使用/storage/06CB-C9CE/
因为/sdcard/
导航到内部存储。tr "\\\\" "/"
give me this error: tr: warning: an unescaped backslash at end of string is not portable
?为什么tr "\\\\" "/"
给我这个错误: tr: warning: an unescaped backslash at end of string is not portable
?The problem was with Windows line delimiters . 问题出在Windows行定界符上 。
Just add the IFS=$'\\r\\n'
above the loop so that the read
command knows the actual line delimiter. 只需在循环上方添加IFS=$'\\r\\n'
,以使read
命令知道实际的行定界符。
IFS=$'\r\n'
while read filename; do
if [ -z "$filename" ]; then continue; fi
adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"
I tried plugging the whole while
-loop into the console and it failed with the same error: 我尝试将整个while
-loop插入控制台,但由于相同的错误而失败:
$ 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
This time I started investigating why the output was broken . 这次我开始调查为什么输出中断了 。 I remembered that windows uses \\r\\n
as newline, which means Carriage Return + Line Feed, (CR+LF) , so some text must have been overwritten. 我记得Windows使用\\r\\n
作为换行符,这意味着回车+换行(CR + LF) ,因此某些文本必须已被覆盖。
It was because of broken values stored inside the $filename
variable. 这是因为$filename
变量中存储的值损坏。
This is the loop from the script: 这是脚本的循环:
while read filename; do
if [ -z "$filename" ]; then continue; fi
adb pull "$srcFolder/$filename" "$dstFolder"
done < "$lsFile"
Since each iteration of the while
-loop reads a line from $lsFile
in the following form: 由于while
-loop的每次迭代都以以下形式从$lsFile
读取一行:
exampleFilename.jpg\r\n
It misinterprets the newline symbols as part of the file name, so adb pull tries to read files with these whitespaces in their names, but fails and it additionally writes a broken output. 它将换行符号误解为文件名的一部分,因此adb pull尝试读取名称中带有这些空格的文件,但是失败,并且还会写入损坏的输出。
Here's a .bat
script that can be run by Windows Command Prompt or Windows PowerShell . 这是一个.bat
脚本,可以由Windows命令提示符或Windows PowerShell运行 。 No Git Bash required. 无需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
to point to your phone camera folder, 只需编辑srcFolder
以指向您的手机摄像头文件夹, dateRegex
for matching the date interval and 将一个模式插入dateRegex
以匹配日期间隔和 .bat
extension, ie: adb-pull-camera-photos.bat
. 将其另存为扩展名为.bat
的文件,即: adb-pull-camera-photos.bat
。 Keep in mind that you still need have adb for Windows on your PC. 请记住,您的PC上仍然需要Windows的adb 。
This might not be the answer but might be useful for others looking for android photo/files backup solution.这可能不是答案,但可能对其他寻找 android 照片/文件备份解决方案的人有用。
I use this script on my Windows with git bash.我在我的 Windows 上使用 git bash 使用这个脚本。 This can be easily used for Linux.这可以很容易地用于 Linux。 A common issue with a long backup process is that it might get interrupted and you might have to restart the entire copy process from start.长时间备份过程的一个常见问题是它可能会中断,您可能必须从头开始重新启动整个复制过程。
This script saves you from this trouble.这个脚本可以让你免于这个麻烦。 You can restart the script or interrupt in between but it will resume copy operation from the point it left.您可以重新启动脚本或在两者之间中断,但它会从它离开的点恢复复制操作。
Just change the rfolder => android folder, lfolder => local folder只需更改 rfolder => android 文件夹,lfolder => 本地文件夹
#!/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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.