[ASUS ZenFone 8] bnsmb:
How to change the home directory for the user root on an Android phone

When working a lot in a shell via adb on an Android phone it's usefull to be able to store some user dependent config files in the home directory of the user. So let's see how that can be implemented on a phone running Android.

Note: The config was done and tested on a phone running OmniROM (based on Android 12)

The home directory for all user used in an (adb) shell on Android is the root directory "/".

Using a home directory for more then one user is not really usefull and in addition on Android "/" is mounted read-only so more or less useless as home directory.

Therefor this should be changed . Unfortunately there is no /etc/passwd file in Android to configure the home directory for a user.

Well, there is an /etc/passwd file (probably for compatibily reasons) but it's empty:

shell@ASUS_I006D:/ $ ls -l /etc/passwd
-rw-r--r-- 1 root root 0 2009-01-01 01:00 /etc/passwd
shell@ASUS_I006D:/ $

And as far as I know there is no other config file to configure the home directory of the user in the Android OS.

So we must implement some work around to get this working.

The shell on Android behaves like normal shells on Linux and executes the file /etc/profile when starting a new session.

In Android /etc is a symbolic link to /system/etc:

root@ASUS_I006D:/ # ls -ld /etc
lrw-r--r-- 1 root root 11 2009-01-01 01:00 /etc -> /system/etc
root@ASUS_I006D:/ #

And in the default config there is no file called profile in that directory:

shell@ASUS_I006D:/ $ ls -l /etc/system/profile
ls: /etc/system/profile: No such file or directory
shell@ASUS_I006D:/ $

Because /system is also mounted read-only we need the magic tool Magisk again to create the file /system/etc/profile.

To create the file /system/etc/profile create these directories and files on the phone as user root (assuming Magisk is already installed on the phone):

root@ASUS_I006D:/ # find /data/adb/modules/initshell/
/data/adb/modules/initshell/
/data/adb/modules/initshell/system
/data/adb/modules/initshell/system/etc
/data/adb/modules/initshell/system/etc/profile
root@ASUS_I006D:/ #

and reboot the phone. After the reboot there should be the writable file /etc/profile:

root@ASUS_I006D:/ # ls -l /etc/profile
-rw-rw-rw- 1 root root 1100 2022-07-14 14:51 /etc/profile
root@ASUS_I006D:/ #

which is in reality the file

/data/adb/modules/initshell/system/etc/profile

Now you can edit the file /etc/profile as user root until it fullfills your requirements (be aware that all changes in that file are now persistent).

To test the changes open a new adb session (you should not close the current adb session to be able to fix an error in the profile if opening a new adb session fails).

This file can now be used to define the home directory for the user. The home directory should be on one of the writable filesystem, e.g. in /data:

# add in /etc/profile
HOME="/data/home/root"
export HOME

and the result is:

root@ASUS_I006D:/ # id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:su:s0

root@ASUS_I006D:/ # echo $HOME
/data/home/root
root@ASUS_I006D:/ #

Note that there is not really a writable filesystem for the user shell so this approach to change the home directory is mainly usable for the user root.

The file /etc/profile can also be used to init some other settings for (adb) sessions (e..g. change the PATH, etc) . This feature can be used for sessions for non-root users also.

For additional user dependent configs you can also create the file .profile in the home directory of the user; the file ${HOME}/.profile will be executed after the execution of the file /etc/profile.

Notes:

Be aware that creating a profile for the user root and changing the home directory for the user root might have some side effects on other processes using the shell!

Therefor it's recommended to use the command "tty -s" to test if the profile is executed in an interactive session:

#
# check if we're running in an interactive session
#
if ! tty -s; then
#
# this is not an interactive session - so we're just doing nothing at all
#
:
else
#
# running in an interactive session
#
...
fi

You can also check if the parent process is the adb daemon to not do anything in non-adb sessions.

ps -fp $PPID| grep adbd >/dev/null
if [ $? -ne 0 ] ; then
#
# not running in an adb session
:
else
#
# running in an adb session
...
fi

For testing purpose I suggest to open at least two shells via adb to be able to fix an error in case opening a new shell fails due to a bug in the profile.

If opening a shell session fails due to an error in the /etc/profile and you do not have another open shell either delete the file /data/adb/modules/initshell/system/etc/profile with a filemanager with root access on the phone or boot the phone from a recovery image (like TWRP) and delete or edit the file /data/adb/modules/initshell/system/etc/profile.

I initially looked at this feature to enable a persistent command history for the shell on the Android phone. But after some google searches I found out that persistent history shells are disabled for the shell binary on Android. So this will not work without recompiling the shell binary.

The attached example for the profile (rename the attached file profile.txt to profile) will use the directory /data/home/root as home directory for the user root and will not change the home directory for other users. The profile will do nothing if not running in an interactive session.

The directory /data/home/root will be created by the profile if it does not yet exist.

As always, if the config is working you should create a real Magisk Module for the profile.

The Magisk Module attached, initshell.zip, can be used to create a Magisk Module with your own profile:

To create a new Magisk Module with your own /etc/profile do:

# create an empty working directory
#
TEMPDIR="/tmp/newdir"

mkdir "${TEMPDIR}"
cd "${TEMPDIR}"

# unpack the zip file in the new directory
#
unzip ../initshell.zip

# now edit the file ${TEMPDIR}/system/etc/profile

# also (optional) edit the files config.sh and module.prop in the new directory to document your changes

# the script customize.sh from the module will be executed once when the module is installed. You might add the code
# create the home directories or any other code here
#

# and recreate the zip file
#
zip -r ../initshell.zip .

Note:

Both attached files are also available from my web site: http://bnsmb.de/My_HowTos_for_Android.html