簡體   English   中英

使用 adb 從手機相機傳輸照片的腳本

[英]Script that will transfer photos from phone camera using adb

故事

我用手機攝像頭拍照和錄制視頻,並將所有這些都保存在我的內部存儲/sdcard 中。 我會定期將它們備份到我的 PC 上,因此我將這些相機照片保存在 PC 存儲中與手機存儲同步。

多年來,我一直通過以下方式將手機相機照片備份到我的 PC:

  1. 將手機插入電腦並允許訪問手機數據
  2. 瀏覽手機存儲 → DCIM → 相機
  3. 等待幾分鍾讓系統加載所有照片的列表
  4. 只復制幾張尚未備份的最新照片

我認為等待幾分鍾加載所有照片是不必要的拖累,所以我下載了adb 平台工具 我已將文件夾 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 -loop。 它給出了以下錯誤

': 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 )。
  • 我已經echo了腳本中的所有變量,並獲得了所有正確的路徑,否則這些路徑可以通過手動方法工作。

camera-ls.txt 文件內容

20190618_124656.jpg
20190618_204522.jpg
20190619_225739.jpg

其他問題

  1. 是否可以在不使用其名稱的情況下導航到外部 SD 卡? 我不得不使用/storage/06CB-C9CE/因為/sdcard/導航到內部存儲。
  2. 為什么tr "\\\\" "/"給我這個錯誤: tr: warning: an unescaped backslash at end of string is not portable

問題出在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 -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

這次我開始調查為什么輸出中斷了 我記得Windows使用\\r\\n作為換行符,這意味着回車+換行(CR + LF) ,因此某些文本必須已被覆蓋。

這是因為$filename變量中存儲的值損壞。

這是腳本的循環:

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

由於while -loop的每次迭代都以以下形式從$lsFile讀取一行:

exampleFilename.jpg\r\n

它將換行符號誤解為文件名的一部分,因此adb pull嘗試讀取名稱中帶有這些空格的文件,但是失敗,並且還會寫入損壞的輸出。

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

亞行照片同步

這可能不是答案,但可能對其他尋找 android 照片/文件備份解決方案的人有用。

我在我的 Windows 上使用 git bash 使用這個腳本。 這可以很容易地用於 Linux。 長時間備份過程的一個常見問題是它可能會中斷,您可能必須從頭開始重新啟動整個復制過程。

這個腳本可以讓你免於這個麻煩。 您可以重新啟動腳本或在兩者之間中斷,但它會從它離開的點恢復復制操作。

只需更改 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM