For example, I want to check if a directory exists on the phone.

R=$(adb shell 'ls /mnt/; echo $?' | tail -1);

$ echo $R

$ if [ "$R" -ne 0 ]; then echo "Path doesn't exist"; else echo "Path exists"; fi
: integer expression expected
Path exists

What's wrong with R? Ok, try it with another variable which is definitely 0.

$ x=0
$ if [ "$x" -ne 0 ]; then echo "Path doesn't exist"; else echo "Path exists"; fi

Path exists

$ echo "|$x|"

$ echo "|$R|"

The second pipe isn't printed. Is there a character after 0? Try to trim:

$ R=$(adb shell 'ls /mnt/; echo $?' | tail -1 | xargs)
$ echo "|$R|"

I'm out of ideas.


adb is adding a carriage-return (aka 0x0d, Ctrl-M, \r, etc) before the line-feed. Probably for ease of use with Windows software that expects lines to end with CR-LF rather than just LF.

You can see this yourself with hexdump aka hd, e.g.:

$ printf "$R" | hd
00000000  30 0d                                             |0.|

Because you only need to return a single value (the exit code). you could use printf instead of echo and redirect all of ls's output to /dev/null on the Android device to avoid printing any newlines (then adb doesn't add a CR):

R="$(adb shell 'ls /mnt/ > /dev/null 2>&1 ; printf $?')"

If your android device doesn't have printf, or if you need to return one or more lines of output from a the android shell, you can use tr -d '\r' or dos2unix or sed 's/\r$//' or similar to strip the CR.

dos2unix and sed are better choices than tr here because they will only strip CRs that are immediately followed by LF, leaving alone any CRs that might be in elsewhere in a line:

$ R="$(adb shell 'ls /mnt/ > /dev/null 2>&1 ; echo $?' | dos2unix)"
$ printf "$R" | hd
00000000  30                                                |0|
  • 'printf not found' – ka3ak Aug 17 '17 at 8:29
  • what kind of android device is that? printf is even on my ancient HTC Desire HD which I just tested this with (running CM7, not original HTC Android). I'll update with solution for android without printf. – cas Aug 17 '17 at 8:32
  • 1
    btw, hexdump aka hd is a good tool for diagnosing all sorts of weird 'huh, WTF?' problems like this. It makes it easy to see exactly what input or output you are getting (with hex bytes and ascii representation in hd's default output format) – cas Aug 17 '17 at 8:38
  • Acer Liquid E2 Duo. Bought 2013 or 2014. Your solution with use of 'tr' works. – ka3ak Aug 17 '17 at 8:39
  • 1
    The culprit is adb, not echo. Adb adds CR, which is very annoying, for example, when you want to do something like adb shell tar -cf - …. – Gilles Aug 17 '17 at 23:00

The other answer does a good job explaining where the asker went wrong. The moral of the story is to be wary of counting characters, since adb might add some.

I wound up doing this

R=$(adb shell 'ls /mnt && echo SUCCESS || echo FAIL' | egrep (SUCCESS|FAIL))
echo $R

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.