2

I tried to make a program in bash to capture raw screenshot in Android and then feed it to the program in computer. But the script code only seems to run twice (earlier it ran 8 times only).

I have manually checked the values of variable multiple times, closing them in quotes or even breaking on conditions in a infinite while loop. Somehow, it always stops after few iterations (earlier it stopped at 8, now stops at only two).

#!/bin/bash
set -x # Debug
# Arguments: [[Sector[0-F]] alternate]
# Grab the screenshot
screencap /sdcard/screen.raw
# Grab the header
sxy=(`od -An -tu -N12 /sdcard/screen.raw`)
x=${sxy[0]}
y=${sxy[1]}
fmt=${sxy[2]}
# If the format is not RGB888, return
if [[ $fmt -ne 1 ]]; then
    return
fi
# Remove the "information", so it is easier to work using dd
tail -c+13 /sdcard/screen.raw > /sdcard/tmpscreen.raw
rm /sdcard/screen.raw
mv /sdcard/tmpscreen.raw /sdcard/screen.raw
# Output screen info
echo -n ":::$x:::$y:::"
maxBytes=$(($x*$y/4)) #one-sixteenth lines
case $1 in
    1 ) curline=$(($x/16)) ;;
    2 ) curline=$(($x/8)) ;;
    3 ) curline=$(($x*3/16)) ;;
    4 ) curline=$(($x/4)) ;;
    5 ) curline=$(($x*5/16)) ;;
    6 ) curline=$(($x*3/8)) ;;
    7 ) curline=$(($x*7/16)) ;;
    8 ) curline=$(($x/2)) ;;
    9 ) curline=$(($x*9/16)) ;;
    A ) curline=$(($x*5/8)) ;;
    B ) curline=$(($x*11/16)) ;;
    C ) curline=$(($x*3/4)) ;;
    D ) curline=$(($x*13/16)) ;;
    E ) curline=$(($x*7/8)) ;;
    F ) curline=$(($x*15/16)) ;;
    * ) curline=0 ;;
esac
line=0
bs=$(($x*4))
# Let the script end and program pull first screen
if [[ ! -f /sdcard/oldscreen.raw ]]; then
    mv /sdcard/screen.raw /sdcard/oldscreen.raw
    return
fi
maxLine=$(($maxBytes/$bs))
truncate -s 0 /sdcard/pull.raw
while [[ ("$curline" < "$y") && ("$line" < "$maxLine") ]]; do
    dd if=/sdcard/screen.raw of=/sdcard/line.raw bs="$bs" count=1 \
     skip="$curline" 2> /dev/null
    dd if=/sdcard/oldscreen.raw of=/sdcard/oldline.raw bs="$bs" \
     count=1 skip="$curline" 2> /dev/null
    # Compare lines
    cmp -s /sdcard/oldline.raw /sdcard/line.raw > /dev/null
    # if don't match add line to out file and increment line counter
    # cmp returns 0 for equal, 1 for unequal and >1 for error
    if [[ $? -ne 0 ]]; then # || $(stat -c%s /sdcard/oldline.raw) -eq 0 
        echo -n "$curline" >> /sdcard/pull.raw
        `cat /sdcard/line.raw >> /sdcard/pull.raw`
        ((line++))
    fi
    echo $curline # Debug
    ((curline++))
done
# Clean up
rm /sdcard/line.raw
rm /sdcard/oldline.raw
rm /sdcard/oldscreen.raw
mv /sdcard/screen.raw /sdcard/oldscreen.raw

What the above program does is:

  1. Puts screen size details onto console
  2. Grabs lines from sector onward (0-F: each is one-sixteenth of screen)
  3. Compares with older screenshot and outputs only the outdated lines (max one-sixteenth at a time) with line numbers [4 chars:To be done using function]
  4. Clean up leaving the current screenshot as old screenshot and the outdated data

It exits in first iteration, if there is no older screenshot.

Edit 1:

The test environment for the above code is:

  • Android device/emulator with USB Debugging turned on
  • Connected via adb bridge (working) on any OS (for computer)
  • Screenshot taken via screencap gives raw format
  • Put the above code to /sdcard/screenshot.sh
  • Running emulator/command prompt
  • Running adb shell(-s _device_)sh /sdcard/screenshot/sh on terminal (assuming that you are in adb path)

Now, when I ran after adding set -x on the second line, I get the following output:

C:\Program Files (x86)\Minimal ADB and Fastboot>adb shell
shell@osprey_ud2:/ $ sh /sdcard/screenshot.sh
+ screencap /sdcard/screen.raw
+ od -An -tu -N12 /sdcard/screen.raw
+ set -A sxy -- 720 1280 1
+ x=720
+ y=1280
+ fmt=1
+ >/sdcard/tmpscreen.raw
+ tail -c+13 /sdcard/screen.raw
+ rm /sdcard/screen.raw
+ mv /sdcard/tmpscreen.raw /sdcard/screen.raw
+ echo -n :::720:::1280:::
:::720:::1280:::+ maxBytes=230400
+ curline=0
+ line=0
+ bs=2880
+ mv /sdcard/screen.raw /sdcard/oldscreen.raw
+ return
shell@osprey_ud2:/ $ sh /sdcard/screenshot.sh
+ screencap /sdcard/screen.raw
+ od -An -tu -N12 /sdcard/screen.raw
+ set -A sxy -- 720 1280 1
+ x=720
+ y=1280
+ fmt=1
+ >/sdcard/tmpscreen.raw
+ tail -c+13 /sdcard/screen.raw
+ rm /sdcard/screen.raw
+ mv /sdcard/tmpscreen.raw /sdcard/screen.raw
+ echo -n :::720:::1280:::
:::720:::1280:::+ maxBytes=230400
+ curline=0
+ line=0
+ bs=2880
+ maxLine=80
+ truncate -s 0 /sdcard/pull.raw
+ 2>/dev/null
+ dd 'if=/sdcard/screen.raw' 'of=/sdcard/line.raw' 'bs=2880' 'count=1' 'skip=0'
+ 2>/dev/null
+ dd 'if=/sdcard/oldscreen.raw' 'of=/sdcard/oldline.raw' 'bs=2880' 'count=1' 'skip=0'
+ >/dev/null
+ cmp -s /sdcard/oldline.raw /sdcard/line.raw
+ >>/sdcard/pull.raw
+ echo -n 0
+ >>/sdcard/pull.raw
+ cat /sdcard/line.raw
+
+ 'let]' line++
+ echo 0
0
+ 'let]' curline++
+ 2>/dev/null
+ dd 'if=/sdcard/screen.raw' 'of=/sdcard/line.raw' 'bs=2880' 'count=1' 'skip=1'
+ 2>/dev/null
+ dd 'if=/sdcard/oldscreen.raw' 'of=/sdcard/oldline.raw' 'bs=2880' 'count=1' 'skip=1'
+ >/dev/null
+ cmp -s /sdcard/oldline.raw /sdcard/line.raw
+ >>/sdcard/pull.raw
+ echo -n 1
+ >>/sdcard/pull.raw
+ cat /sdcard/line.raw
+
+ 'let]' line++
+ echo 1
1
+ 'let]' curline++
+ rm /sdcard/line.raw
+ rm /sdcard/oldline.raw
+ rm /sdcard/oldscreen.raw
+ mv /sdcard/screen.raw /sdcard/oldscreen.raw
shell@osprey_ud2:/ $ sh /sdcard/screenshot.sh
+ screencap /sdcard/screen.raw
+ od -An -tu -N12 /sdcard/screen.raw
+ set -A sxy -- 720 1280 1
+ x=720
+ y=1280
+ fmt=1
+ >/sdcard/tmpscreen.raw
+ tail -c+13 /sdcard/screen.raw
+ rm /sdcard/screen.raw
+ mv /sdcard/tmpscreen.raw /sdcard/screen.raw
+ echo -n :::720:::1280:::
:::720:::1280:::+ maxBytes=230400
+ curline=0
+ line=0
+ bs=2880
+ maxLine=80
+ truncate -s 0 /sdcard/pull.raw
+ dd 'if=/sdcard/screen.raw' 'of=/sdcard/line.raw' 'bs=2880' 'count=1' 'skip=0'
1+0 records in
1+0 records out
2880 bytes transferred in 0.001 secs (2880000 bytes/sec)
+ dd 'if=/sdcard/oldscreen.raw' 'of=/sdcard/oldline.raw' 'bs=2880' 'count=1' 'skip=0'
1+0 records in
1+0 records out
2880 bytes transferred in 0.001 secs (2880000 bytes/sec)
+ cmp -s /sdcard/oldline.raw /sdcard/line.raw
+ >>/sdcard/pull.raw
+ echo -n 0
+ >>/sdcard/pull.raw
+ cat /sdcard/line.raw
+
+ 'let]' line++
+ echo 0
0
+ 'let]' curline++
+ dd 'if=/sdcard/screen.raw' 'of=/sdcard/line.raw' 'bs=2880' 'count=1' 'skip=1'
1+0 records in
1+0 records out
2880 bytes transferred in 0.001 secs (2880000 bytes/sec)
+ dd 'if=/sdcard/oldscreen.raw' 'of=/sdcard/oldline.raw' 'bs=2880' 'count=1' 'skip=1'
1+0 records in
1+0 records out
2880 bytes transferred in 0.001 secs (2880000 bytes/sec)
+ cmp -s /sdcard/oldline.raw /sdcard/line.raw
+ >>/sdcard/pull.raw
+ echo -n 1
+ >>/sdcard/pull.raw
+ cat /sdcard/line.raw
+
+ 'let]' line++
+ echo 1
1
+ 'let]' curline++
+ rm /sdcard/line.raw
+ rm /sdcard/oldline.raw
+ rm /sdcard/oldscreen.raw
+ mv /sdcard/screen.raw /sdcard/oldscreen.raw
shell@osprey_ud2:/ $

My take on output: It didn't go into the if statement as I was checking $? -ne 1 instead of $? -ne 0. So, I made the correction, but it still exited after the second iteration.

So, I removed the output to /dev/null to see what was wrong. But that only gave me more output and no info on why the loop exits.

Community
  • 1
  • 1
  • 4
    did you run it with `set -x` to see values being set? Good luck. – shellter Jan 15 '16 at 03:33
  • If you still need help with this, consider extending your Q with code that will setup a test environment that people can use. As is, it seems like a lot of work with pkgs we may not have installed to try to run your code. (Interesting code!, but ... a lot of work to debug without the proper environment). Good luck! – shellter Jan 15 '16 at 15:11

1 Answers1

0

Checkout the operator syntax for your shell http://www.tldp.org/LDP/abs/html/comparison-ops.html

Your while loop should probably be something like this (-lt instead of <)

while [[ ("$curline" -lt "$y") && ("$line" -lt "$maxLine") ]]
ayvazj
  • 3,943
  • 1
  • 14
  • 14