I have a rather weird issue. I can't figure out why it's happening or how to fix it.
The script:
#!system/bin/sh
#set -x
reader() {
t2=-1
grep -v -E "add device|name:" | while IFS=' ' read -r t1 a b c d _; do
t1=${t1%%-*}
t=`expr $t1 - $t2`
if let 't > 0 && t2 > -1'; then
echo "sleep $t"
fi
printf 'sendevent %s' "${a%?}"
printf '%5d %5d %5d\n' "0x$b" "0x$c" "0x$d"
t2=$t1
done
}
let() {
IFS=, command eval [ '$(($*))' -ne 0 ]
}
countDown() {
echo 'Starting in...'
i=4
while [[ $i -gt 1 ]]; do
i=$(($i-1))
echo "$i"
sleep 1
done
printf '%s\n\n\n' 'Go!'
# echo "$*"
"$#" | reader
}
clear
printf '%s >' 'Catch by [n]umber of events or [t]imeout?'
read type
case $type in
n)
printf '%s >' 'Events to catch?'
read arg
echo "Gonna catch $arg events!"
countDown getevent -t -c "$arg"
;;
t)
printf '%s >' 'Timeout (in seconds)?'
read arg
echo "Gonna catch events for $arg seconds!"
countDown timeout -t $arg getevent -t
esac
The goal of the script:
Catch the user's interactions (e.g. key presses, screen taps, etc) using the getevent command and outputs a script to stdout, that can be used to replicate these events.
Additional info:
getevent's output is in hexadecimal format
sendevent accepts decimal format
Expected output:
Catch by [n]umber or by [t]imeout? n
Events to catch? > 4
Gonna catch 4 events...
Starting in...
3
2
1
Go!
sendevent /dev/input/event5 1 102 1
sendevent /dev/input/event5 0 0 0
sleep 3
sendevent /dev/input/event5 1 102 0
sendevent /dev/input/event5 0 0 0
The problem:
The code runs as expected when "n" is picked. When "t" is picked, the script exits after the specified amount of seconds. However, it does not output anything - the first line of the while loop doesn't even run.
With set -x, here's what's shown (last few lines):
+ printf %s\n\n\n Go!
Go!
+ reader
+ t2=-1
+ grep -v -E add device|name:
+ timeout -t 5 getevent -t
+ IFS = read -r t1 a b c d _
Running this alone shows output to stdout (output that's supposed to be read and modified inside the while loop):
timeout -t 5 getevent -t
Any ideas?
Thanks.
EDIT:
Alright, so I think it's a buffering issue. Basically this gives a similar issue:
getevent > output
The file gets updated every bunch of events, but not instantly (and might never update if not enough events are made). I'm not aware of any work around on Android.
I think there's no way of enabling line-buffering in busybox's grep, but you can do something like this:
$ adb shell timeout -t 10 getevent -t | \
grep --line-buffered -v -E "add device|name:" | \
while read line; do echo "READ: $line"; done
Here was basically that stuff I translated from your code before being mangled by bug workarounds. Replacing the one command I don't have with cat on the timeout branch, it runs correctly with your sample input in Busybox sh, dash, mksh, bash, and ksh93.
Since so many basic things about the shell and applications are broken, it isn't surprising this doesn't work. I would make sure Busybox is up-to-date and see whether the arithmetic and other bugs you keep hitting are reproducible on other systems, and report bugs if this code doesn't work.
#!/bin/sh
reader() {
t2=-1
grep -vE '^(add device|[[:space:]]+name:)' |
while IFS=' ' read -r t1 a b c d _; do
let "(t = (t1 = ${t1%%-*}) - t2) > 0 && t2 > -1" && echo "sleep $t"
printf 'sendevent %s' "${a%[[:digit:]]:}"
printf '%5d %5d %5d\n' "0x$b" "0x$c" "0x$d"
let t2=t1
done
}
let() {
IFS=, command eval test '$(($*))' -ne 0
}
countDown() {
echo 'Starting in...'
i=4
while let 'i-=1 > 0'; do
echo "$i"
sleep 1
done
printf '%s\n\n\n' 'Go!'
echo "$*"
"$#" <&3 | reader
}
isDigit() {
while ! ${1+false}; do
case $1 in
*[^[:digit:]]*|'') return 1
esac
command shift
done 2>/dev/null
}
main() {
printf '%s >' 'Catch by [n]umber of events or [t]imeout?'
read type
case $type in
n)
printf '%s >' 'Events to catch?'
read arg
isDigit "$arg" || return 1
echo "Gonna catch $arg events!"
countDown getevent -t -c "$arg"
;;
t)
printf '%s >' 'Timeout (in seconds)?'
read arg
isDigit "$arg" || return 1
echo "Gonna catch events for $arg seconds!"
countDown busybox timeout -t "$arg" cat -
;;
*)
return 1
esac
}
main "$#" 4<&0 <<\EOF 3<&0 <&4 4<&-
add device 1: /dev/input/event8
name: "bcm_headset"
add device 2: /dev/input/event7
name: "max8986_ponkey"
add device 3: /dev/input/event6
name: "sec_touchscreen"
add device 4: /dev/input/event5
name: "sec_keypad"
add device 5: /dev/input/event4
name: "orientation"
add device 6: /dev/input/event3
name: "accelerometer"
add device 7: /dev/input/event0
name: "proximity_sensor"
add device 8: /dev/input/event2
name: "geomagnetic_raw"
add device 9: /dev/input/event1
name: "geomagnetic"
45534-48646 /dev/input/event6: 0001 008b 00000001
45534-48646 /dev/input/event6: 0000 0000 00000000
45534-48646 /dev/input/event6: 0001 008b 00000000
45534-48646 /dev/input/event6: 0000 0000 00000000
EOF
# vim: set fenc=utf-8 ff=unix ft=sh :
Output:
$ bb --help
BusyBox v1.21.0 (2013-02-20 20:39:21 CST) multi-call binary.
Usage: bb [-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]
Unix shell interpreter
$ bb answers/countdown
Catch by [n]umber of events or [t]imeout? >t
Timeout (in seconds)? >5
Gonna catch events for 5 seconds!
Starting in...
3
2
1
Go!
busybox timeout -t 5 cat -
sendevent /dev/input/event6: 1 139 1
sendevent /dev/input/event6: 0 0 0
sendevent /dev/input/event6: 1 139 0
sendevent /dev/input/event6: 0 0 0
Had the same problem, and remembered a trick that I first used in MS-DOS 3.30, and later in Cygwin(not for timeout, but the more command is a magical bullet for lots of redirect problems):
timeout -t 8 getevent | more > getevent.txt
works well in Total Commander's shell
with su (not sh)
You're welcome :-)
Related
I'm trying to repurposed my Sony Xperia Z3 Compact into a lcd display project. In order to proceed, I would like to mod my Xperia phone so that the phone will automatically turn on when charger turn ON. I search around and found some script like https://android.stackexchange.com/questions/20021/automatically-power-on-android-when-the-charger-is-connected and some people mentioned that I should mod chargemon file. But when I replace this file, my phone cannot boot into the system.
#!/system/bin/sh
/system/bin/reboot
While checking the file, I notice that there 2 file chargemon and another is chargemon.stock. attached here chargemonfile . Actually this file have been edited during rooting process which I get it from xda forum https://forum.xda-developers.com/z3-compact/general/recovery-root-mm-575-lb-t3418714
#!/system/xbin/busybox sh
BUSYBOX=/system/xbin/busybox
VIB=/sys/class/timed_output/vibrator/enable
R_LED=/sys/class/leds/led:rgb_red/brightness
G_LED=/sys/class/leds/led:rgb_green/brightness
B_LED=/sys/class/leds/led:rgb_blue/brightness
LOG="/cache/mm_twrp_recovery.log"
WORKDIR="/cache/mm_twrp_recovery_keycheck"
MKDIR="${BUSYBOX} mkdir"
CHOWN="${BUSYBOX} chown"
CHMOD="${BUSYBOX} chmod"
TOUCH="${BUSYBOX} touch"
CAT="${BUSYBOX} cat"
SLEEP="${BUSYBOX} sleep"
KILL="${BUSYBOX} kill"
RM="${BUSYBOX} rm"
PS="${BUSYBOX} ps"
GREP="${BUSYBOX} grep"
AWK="${BUSYBOX} awk"
EXPR="${BUSYBOX} expr"
MOUNT="${BUSYBOX} mount"
LS="${BUSYBOX} ls"
HEXDUMP="${BUSYBOX} hexdump"
CP="${BUSYBOX} cp"
${RM} -f ${LOG}
echo "chargemon" >> ${LOG}
BOOTTWRP=0
if [ -e "/cache/recovery/boot" ]; then
echo " /cache/recovery/boot file found" >> ${LOG}
${RM} -f /cache/recovery/boot
echo 255 > ${R_LED}
echo 0 > ${G_LED}
echo 255 > ${B_LED}
BOOTTWRP=1
else
if [ ! -d "${WORKDIR}" ]; then
${MKDIR} ${WORKDIR}
${CHOWN} system.cache ${WORKDIR}
${CHMOD} 770 ${WORKDIR}
fi
if [ ! -e ${WORKDIR}/keycheck ]; then
${RM} ${WORKDIR}/keyevent*
${RM} ${WORKDIR}/keycheck_down
${RM} ${WORKDIR}/ps*
fi
echo 0 > ${R_LED}
echo 255 > ${G_LED}
echo 0 > ${B_LED}
echo 150 > ${VIB}
for EVENTDEV in $(${LS} /dev/input/event* ); do
SUFFIX="$(${EXPR} ${EVENTDEV} : '/dev/input/event\(.*\)')"
${CAT} ${EVENTDEV} > ${WORKDIR}/keyevent${SUFFIX} &
done
${SLEEP} 2
${PS} > ${WORKDIR}/ps.log
${CHMOD} 660 ${WORKDIR}/ps.log
for CATPROC in $(${PS} | ${GREP} /dev/input/event | ${GREP} -v grep | ${AWK} '{print $1}'); do
${KILL} -9 ${CATPROC}
done
${HEXDUMP} ${WORKDIR}/keyevent* | ${GREP} -e '^.* 0001 0072 .... ....$' > ${WORKDIR}/keycheck_down
if [ -s ${WORKDIR}/keycheck_down ]; then
echo " keycheck volume down - ok" >> ${LOG}
echo 255 > ${R_LED}
echo 0 > ${G_LED}
echo 255 > ${B_LED}
BOOTTWRP=1
fi
fi
if [ $BOOTTWRP -eq 1 ]; then
echo " remount rootfs rw" >> ${LOG}
mount -o remount,rw rootfs / 2>> ${LOG}
echo " copy busybox to /sbin" >> ${LOG}
${CP} /system/etc/mm_twrp_recovery/busybox /sbin
${CHOWN} 0.2000 /sbin/busybox
${CHMOD} 755 /sbin/busybox
BUSYBOX=/sbin/busybox
echo " copy boot_twrp_recovery.sh to /sbin" >> ${LOG}
${CP} /system/etc/mm_twrp_recovery/boot_twrp_recovery.sh /sbin
${CHOWN} 0.0 /sbin/boot_twrp_recovery.sh
${CHMOD} 755 /sbin/boot_twrp_recovery.sh
echo " copy recovery.twrp.cpio.lzma to /sbin" >> ${LOG}
${CP} /system/etc/mm_twrp_recovery/recovery.twrp.cpio.lzma /sbin
${CHOWN} 0.0 /sbin/recovery.twrp.cpio.lzma
${CHMOD} 644 /sbin/recovery.twrp.cpio.lzma
echo " unpack recovery.twrp.cpio.lzma" >> ${LOG}
${BUSYBOX} lzma -d /sbin/recovery.twrp.cpio.lzma
echo " exec boot_twrp_recovery.sh (twrp boot)" >> ${LOG}
exec /sbin/boot_twrp_recovery.sh
fi
echo 0 > ${B_LED}
echo 0 > ${R_LED}
echo 0 > ${G_LED}
echo " exec chargemon.stock (regular boot)" >> ${LOG}
exec /system/bin/chargemon.stock
exit 0
So im thinking, I shouldn't replace this file entirely but just add another line of code. Now, if anyone have experience regarding this maybe can share some input or help me modify the existing script.
My main goal is to get my xperia phone turn on when im plugin the charger.
Got it working by comment out this line exec /system/bin/chargemon.stock
Ref: https://z4-forum.com/forum/viewtopic.php?t=56746&start=90
I'm trying to detect the bitness (32 or 64 bit) of an ELF binary in the bash shell of an android device.
I don't have file, objdump or readelf, which are the obvious answers on a real Linux system. Additionally, I don't have head, tail, sed, awk, grep or perl.
I've seen in the ELF header description that the e_ident[EI_CLASS] field of the binary header should contain a byte which describes the bitness. Maybe I could use that? But I'm having trouble teasing that byte out of the file with such a limited toolset.
Thanks to Charles Duffy's answer to How do I read first line using cat, I found a way to read only the bytes I needed out of the file:
$ # Read 5 bytes of the 'adb' binary.
$ read -r -n 5 elf_header < /system/bin/adb; echo $elf_header | cat -v
^?ELF^A
If the 7th character of that output is "A", then the binary is 32-bit. If it's "B", then 64-bit.
https://en.wikipedia.org/wiki/Executable_and_Linkable_Format
head -c 20 ${executable} | tail -c 2 will get you the 2 bytes for e_machine. Then you can do further processing on that. Eg, x86 may be either 32-bit or 64-bit while x86-64 is 64-bit.
Alternatively, if you're specifically looking for the bitness of the ELF container (as opposed to the executable code), which implies the requirements of the code, you might try looking at e_ident[EI_CLASS]:
head -c 5 ${executable} | tail -c 1. If the byte is 0x01, it's 32 bit. If it's 0x02, it's 64 bit. If it's anything else, it's undefined at this time.
Edit:
Recommended reading (hehe pun intended) describes the difference between -n and -N.
So without the use of head and tail, this would be better:
read -r -N 5 elf_header < ${executable} && echo -n "${elf_header:4:1}"
At this point, the single character that was echoed to stdout would be "\\x1" for 32-bit and "\\x2" for 64-bit. In a more complete linux environment you can pass that through xxd to see a hex dump. You can check the bit with this 1-liner:
bitness32=$(printf "\\x1") && bitness64=$(printf "\\x2") && read -r -N 5 elf_header < ~/a.out && elf_bitness="${elf_header:4:1}" && { [[ "${bitness32}" == "${elf_bitness}" ]] && echo "32-bit"; } || { [[ "${bitness64}" == "${elf_bitness}" ]] && echo "64-bit"; } || { echo "???"; }
Using printf and dd:
#!/bin/sh
elf32="$(printf "\177ELF\001")"
elf64="$(printf "\177ELF\002")"
header="$(dd bs=5 seek=0 count=1 "if=$1" 2> /dev/null)"
case "$header" in
"$elf32") echo ELF32 ;;
"$elf64") echo ELF64 ;;
*) exit 1 ;;
esac
Is it possible to also display the Log's Package Name in each line?
Using
logcat -v long
leaves exactly the package name field (after PID) empty.
I want to filter the Logs from a specific application with different Tags, just wondering if it is possible.
logcat record does not have a "package name field". Therefore there is no standard/built-in way to filter by it.
Although since Android 7.0 you can use logcat --pid option combined with pidof -s command to filter output by binary/package name:
adb shell "logcat --pid=$(pidof -s <package_name>)"
Replace " with ' for Linux/MacOS
This is my script. A little rusty but still working.
PID=`adb shell ps | grep -i <your package name> | cut -c10-15`;
adb logcat | grep $PID
Actually I have a python script to add more colours, and a while loop to keep monitoring for that process when it gets restarted, but I think you'll get the point.
Option 1
Enter these line by line:
adb shell
su
bash
PKG_PID_LIST_CACHE=$(eval $(pm list packages | cut -d ':' -f 2 | sed 's/^\(.*\)$/echo \"\$\(echo \1\) \$\(pidof \1\)\";/'))
PROC_PID_LIST_CACHE=$(ps -A -o NAME -o PID)
PID_LIST_CACHE=$(echo "$PKG_PID_LIST_CACHE\n$PROC_PID_LIST_CACHE")
function pid2pkg() { pkgName=$(echo "$PID_LIST_CACHE" | grep -w $1 | cut -d ' ' -f1 | head -1); if [ "$pkgName" != "" ] ; then echo $pkgName; else echo "*NOT RUNNING*"; fi }
eval "$(logcat -d | sed -r -e 's/([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)/\2 \$\(pid2pkg \3\) \5/g' | sed -r -e 's/(.+)/echo -e \"\1\"/g')"
The logcat output will be in the following format:
[Time] [Name] [Type] [Message]
Example:
14:34:59.386 wpa_supplicant E wpa_supplicant: nl80211: Failed to set IPv4 unicast in multicast filter
14:35:02.231 com.android.phone D TelephonyProvider: subIdString = 1 subId = 1
14:35:03.469 android.hardware.wifi#1.0-service E WifiHAL : wifi_get_logger_supported_feature_set: Error -3 happened.
14:35:03.518 system_server I WifiService: getWifiApEnabledState uid=10086
14:35:03.519 dev.ukanth.ufirewall D AFWall : isWifiApEnabled is false
14:35:03.520 system_server I GnssLocationProvider: WakeLock released by handleMessage(UPDATE_NETWORK_STATE, 0, 123)
14:35:03.522 dev.ukanth.ufirewall I AFWall : Now assuming wifi connection
Some system processes don't have packages. system_server and wpa_supplicant for instance. If a package name can't be found, the process name will be displayed instead.
Caveats:
If the process behind a certain PID is not running anymore, you can't get the package/process name anymore.
After a process exited itself or your device restarted, the PIDs may actually be assigned to completely different processes.
So you might want to check for how long the process has actually been running:
ps -e -o pid -o stime -o name
Option 2
If you want the formatting to be a bit more readable, you can copy my logging script to your device and execute it:
better_logging.sh
PKG_PID_LIST_CACHE=$(eval $(pm list packages | cut -d ':' -f 2 | sed 's/^\(.*\)$/echo \"\$\(echo \1\) \$\(pidof \1\)\";/'))
PROC_PID_LIST_CACHE=$(ps -A -o NAME -o PID)
PID_LIST_CACHE=$(echo "$PKG_PID_LIST_CACHE\n$PROC_PID_LIST_CACHE")
MAX_LEN=$(echo "$PID_LIST_CACHE" | cut -d ' ' -f1 | awk '{ if ( length > L ) { L=length} }END{ print L}')
function pid2pkg() {
pkgName=$(echo "$PID_LIST_CACHE" | grep -w $1 | cut -d ' ' -f1 | head -1);
if [ "$pkgName" != "" ] ; then
printf "%-${MAX_LEN}s" "$pkgName";
else
printf "%-${MAX_LEN}s" "<UNKNOWN (NOT RUNNING)>";
fi
}
eval "$(\
logcat -d | \
sed -r -e 's/([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+) +(.*)/\2\ $\(pid2pkg \3\) \5/g' | \
sed -r -e 's/(.+)/echo -e \"\1\"/g' \
)" | \
awk '
function color(c,s) {
printf("\033[%dm%s\033[0m\n",90+c,s)
}
/ E / {color(1,$0);next}
/ D / {color(2,$0);next}
/ W / {color(3,$0);next}
/ I / {color(4,$0);next}
{print}
'
To copy and run it, you can use:
adb push better_logging.sh /sdcard/better_logging.sh
adb shell "bash /sdcard/better_logging.sh"
Output will look like this:
This works with awk.
adb logcat | grep -F "`adb shell ps | grep com.yourpackage | awk '{print $2;}'`"
When bash (or other shell) fails to guess the correct column count on your terminal, it gets inconvenient to edit long lines.
For usual Linux systems, there is script termsize that automatically fixes the terminal size. But typical Android does not have Python, so termsize can't work.
How do I fix the terminal width in adb shell?
This snippet can assist you for setting up column count:
echo "\033[18t"; { sleep 1; echo -n "COLUMNS="; } & grep -m 1 -o '[0-9]*t' | { sleep 2; grep -m 1 -o '[0-9]*'; }
Usage:
Open adb shell;
Insert the snippet into command line;
Execute it (press Enter) and immediately press Enter again.
Wait for 2 seconds: it should print COLUMNS= after 1 second and the columns count after another 1 second;
Copy COLUMNS=NNN into console and press Enter yet again.
Example session:
$ adb shell
9]*t' | { sleep 2; grep -m 1 -o '[0-9]*'; } <
[1] 17212
^[[8;38;149t
COLUMNS=149
[1] + Done { sleep 1 ; echo -n "COLUMNS=" ; }
shell#hwH60:/ $ COLUMNS=149
shell#hwH60:/ $
It is really annoying if you adb push/pull large files to the device that there's no way to now how far along it is. Is it possible to run adb push or adb pull and get a progress bar using the 'bar' utility?
The main issue here is I think that adb expects two file names, if the input file could be replaced by stdin you could pipe through the 'bar' utility and get a progress bar. So far I haven't succeeded in doing so, but I'm not really a shell guru which is why I'm asking here :)
Note that I'm on Linux using bash.
It looks like the latest adb has progress support.
Android Debug Bridge version 1.0.32
device commands:
adb push [-p] <local> <remote>
- copy file/dir to device
('-p' to display the transfer progress)
However, the answers above also work for 'adb install' which do not have a progress option. I modified the first answer's script to work this way:
Create "adb-install.sh" somewhere in your PATH and run "adb-install.sh " instead of "adb install -f "
#!/bin/bash
# adb install with progressbar displayed
# usage: <adb-install.sh> <file.apk>
# original code from: http://stackoverflow.com/questions/6595374/adb-push-pull-with-progress-bar
function usage()
{
echo "$0 <apk to install>"
exit 1
}
function progressbar()
{
bar="================================================================================"
barlength=${#bar}
n=$(($1*barlength/100))
printf "\r[%-${barlength}s] %d%%" "${bar:0:n}" "$1"
# echo -ne "\b$1"
}
export -f progressbar
[[ $# < 1 ]] && usage
SRC=$1
[ ! -f $SRC ] && { \
echo "source file not found"; \
exit 2; \
}
which adb >/dev/null 2>&1 || { \
echo "adb doesn't exist in your path"; \
exit 3; \
}
SIZE=$(ls -l $SRC | awk '{print $5}')
export ADB_TRACE=all
adb install -r $SRC 2>&1 \
| sed -n '/DATA/p' \
| awk -v T=$SIZE 'BEGIN{FS="[=:]"}{t+=$7;system("progressbar " sprintf("%d\n", t/T*100))}'
export ADB_TRACE=
echo
echo 'press any key'
read n
Currently I have this little piece of bash:
function adb_push {
# NOTE: 65544 is the max size adb seems to transfer in one go
TOTALSIZE=$(ls -Rl "$1" | awk '{ sum += sprintf("%.0f\n", ($5 / 65544)+0.5) } END { print sum }')
exp=$(($TOTALSIZE * 7)) # 7 bytes for every line we print - not really accurate if there's a lot of small files :(
# start bar in the background
ADB_TRACE=adb adb push "$1" "$2" 2>&1 | unbuffer -p awk '/DATA/ { split($3,a,"="); print a[2] }' | unbuffer -p cut -d":" -s -f1 | unbuffer -p bar -of /dev/null -s $exp
echo # Add a newline after the progressbar.
}
It works somewhat, it shows a progress bar going from 0 to 100 which is nice. However, it won't be correct if you do a lot of small files, and worse, the bytes/s and total bytes shown by 'bar' aren't correct.
I challenge you to improve on my script; it shouldn't be hard! ;)
Here is my solution, it will show a simple progressbar and current numeric progress
[==================================================] 100%
Usage
./progress_adb.sh source destination
progress_adb.sh
#!/bin/bash
function usage()
{
echo "$0 source destination"
exit 1
}
function progressbar()
{
bar="=================================================="
barlength=${#bar}
n=$(($1*barlength/100))
printf "\r[%-${barlength}s] %d%%" "${bar:0:n}" "$1"
# echo -ne "\b$1"
}
export -f progressbar
[[ $# < 2 ]] && usage
SRC=$1
DST=$2
[ ! -f $SRC ] && { \
echo "source file not found"; \
exit 2; \
}
which adb >/dev/null 2>&1 || { \
echo "adb doesn't exist in your path"; \
exit 3; \
}
SIZE=$(ls -l $SRC | awk '{print $5}')
ADB_TRACE=adb adb push $SRC $DST 2>&1 \
| sed -n '/DATA/p' \
| awk -v T=$SIZE 'BEGIN{FS="[=:]"}{t+=$7;system("progressbar " sprintf("%d\n", t/T*100))}'
echo
Testing on Ubuntu 14.04
$ bash --version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
TODO
directory support
progressbar size change when screen size change
Well I can give you an Idea:
ADB_TRACE=adb adb push <source> <destination>
returns logs for any command, so for example the copy command, which looks like:
writex: fd=3 len=65544: 4441544100000100000000021efd DATA....#....b..
here you can get the total bytes length before, with ls -a, then parse the output of adb with grep or awk, increment an interneral counter and send the current progress to the bar utility.
When you succeeded, please post the script here.