Topper Harley
Topper Harley

Reputation: 12374

bash: Retrieving Android image filenames over adb shell

Here's a one-liner that is driving me nuts:

$ adb shell ls /sdcard/DCIM/Camera | grep IMG_20150630|while read f; do echo "pull /sdcard/DCIM/Camera/$f"; done
pull /sdcard/DCIM/Camera/IMG_20150630_091806.jpg
pull /sdcard/DCIM/Camera/IMG_20150630_091817.jpg
pull /sdcard/DCIM/Camera/IMG_20150630_091819.jpg
pull /sdcard/DCIM/Camera/IMG_20150630_091822.jpg
pull /sdcard/DCIM/Camera/IMG_20150630_091842.jpg
pull /sdcard/DCIM/Camera/IMG_20150630_175231:nopm:.jpg
pull /sdcard/DCIM/Camera/IMG_20150630_175340:nopm:.jpg
pull /sdcard/DCIM/Camera/IMG_20150630_222520.jpg

Fine. Now I want to add something after $f:

$ adb shell ls /sdcard/DCIM/Camera | grep IMG_20150630|while read f; do echo "pull /sdcard/DCIM/Camera/$f ./"; done
 ./l /sdcard/DCIM/Camera/IMG_20150630_091806.jpg
 ./l /sdcard/DCIM/Camera/IMG_20150630_091817.jpg
 ./l /sdcard/DCIM/Camera/IMG_20150630_091819.jpg
 ./l /sdcard/DCIM/Camera/IMG_20150630_091822.jpg
 ./l /sdcard/DCIM/Camera/IMG_20150630_091842.jpg
 ./l /sdcard/DCIM/Camera/IMG_20150630_175231:nopm:.jpg
 ./l /sdcard/DCIM/Camera/IMG_20150630_175340:nopm:.jpg
 ./l /sdcard/DCIM/Camera/IMG_20150630_222520.jpg

WTF?! The chars added after $f are actually added to the begining of every line.

Mac OS X 10.10.4, using GNU bash, version 4.3.30(1)-release (x86_64-apple-darwin14.0.0)

Upvotes: 0

Views: 213

Answers (2)

Topper Harley
Topper Harley

Reputation: 12374

There was a CR. I guess that adb returns a CRLF for every line? Weird, there's no Windows involved here.

$ adb shell ls /sdcard/DCIM/Camera | grep IMG_20150630|head -n 1 |xxd
0000000: 494d 475f 3230 3135 3036 3330 5f30 3931  IMG_20150630_091
0000010: 3830 362e 6a70 670d 0a                   806.jpg..

Upvotes: 1

Charles Duffy
Charles Duffy

Reputation: 295272

Using a NUL-delimited stream is the better approach for transporting arbitrary filenames over the wire. (Now, if you have CRs being transformed to CRLF somewhere in your stack, that's a separate issue -- but this will also avoid it, unless your filenames contain literal CRs).

#!/bin/bash
while IFS= read -r -d ''; do
  printf 'pull %q\n' "$REPLY"
done < <(adb shell printf '%s\0' /sdcard/DCIM/Camera/*IMG_20150630*)

The use of %q will also escape hidden characters in your output in a human-readable manner, making it easier to see what's going on if you have unusual behavior in the future.

Upvotes: 0

Related Questions