This is an old question, but I was recently curious about this myself. I found a method that doesn't require recompiling adbd
, however it does require su
(I'm using Chainfire SuperSu 2.45).
Assuming bash
is located at /system/bin/bash
, and su
is at /system/xbin/su
, it's essentially something like this:
adb shell
(use an interactive shell. Invoking this process as a
one-liner could cause ADB to cease working if there is a problem)
mount -o remount,rw /system
mv /system/bin/sh /system/bin/sh.bak
echo -e '#!/system/bin/bash\n/system/xbin/su -mm -l -s /system/xbin/bash' > /system/bin/sh
Note that your paths may differ; use which bash
and which su
to be sure.
chmod 777 /system/bin/sh
- Test the shell before you exit:
/system/bin/sh
. If you get an error, fix the error or revert by restoring the backup: cp /system/bin/sh.bak /system/bin/sh
.
- Optionally remount /system; most devices will do this automatically:
mount -o remount,ro /system
And you're done.
Simply symlinking BASH to SH doesn't work because bash emulates SH when invoked this way.
However, having a look at strace, it does seem to look for a bashrc
when a symlinked BASH is called as 'sh --login'. While this could conceivably be used to "chainload" shells via script, as mentioned above the way adbd
invokes SH is hardcoded.
If there is a problem and you have removed (or moved) /system/bin/sh
ADB wont have a shell to give you to fix the problem. If this happens, you have a few options:
- Reboot into a recovery that has
adbd
(such as CWM or TWRP) and open an adb shell to it, to copy /system/bin/sh.bak over to /system/bin/sh again.
- Use adb to copy the backup:
adb root; adb remount; adb shell; adb pull /system/bin/sh.bak; adb push sh.bak /system/bin/sh
Note that this won't work on all devices; some refuse to allow adb to remount /system rw in this way.
- Use a terminal emulator that can be set to run a different shell; note that several will try /system/bin/sh first and force close.
sh
, notbash
, when I use adb to connect. What build are you using?