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).
bash is located at
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.