4

I own a rooted Samsung Galaxy S Relay 4G running stock Android 4.1.2.

If you have Android 6.0 "Marshmallow" or better, then you have Toybox. This is a package of command-line tools, handy for advanced users who sometimes use a terminal emulator. Unfortunately, Android 4.1.2 does not include Toybox. Instead, it includes some other tools which aren't as nice to use.

Sometimes I use the terminal emulator written by Jack Palevich; other times I use adb shell from a laptop.

  1. Would it make more sense to install Toybox to my system partition, or to my data partition? Both partitions have far more than enough free space.

  2. When a command is provided both by Android and by Toybox, I want the Toybox version to win. On Linux, I might install Toybox to /home/unforgettableid/bin or /usr/local or /opt. Could you please suggest a sensible place for me to install Toybox (and its large collection of symlinks) on my phone?

[Edit: I wonder what the various BusyBox installers do. Also, I wonder how Android sets the PATH environment variable. As well, I also wonder whether or not there's a way for me to change that variable and to make my change persist across reboots. Finally, I wonder whether or not putting the Toybox tools first in my PATH would be likely to break things in non-obvious ways.]


Possibly related: "Android Folder Hierarchy".

0

2 Answers 2

5

Where should I install Toybox?

Would it make more sense to install Toybox to my system partition, or to my data partition?

Depends. If you don't plan to factory reset the phone ever again, you can choose data partition, else, choose system partition.

When a command is provided both by Android and by Toybox, I want the Toybox version to win.

The PATH variable contains the location of the directories containing executable binaries. Should you decide to keep a separate directory for your symlinks, configure $PATH to search for a command into your directory first. If it finds one, it will execute it.

On Linux, I might install Toybox to /home/unforgettableid/bin or /usr/local or /opt. Could you please suggest a sensible place for me to install Toybox (and its large collection of symlinks) on my phone?

All those locations don't exist for Android. Since you're using Android 4.1.2, I suppose you would be having your external SD card formatted with a FAT filesystem. Symlinks don't work on FAT filesystems (not on FAT32 or vfat at least) so your best bet is to install under /data or /system.

Alternatively, you can make an image under your external SD card, format that image with a filesystem supported by your Android's kernel (often EXT2 | EXT3 | EXT4), then mount it in the device anywhere in loopback mode. I've not tried this method though.

I wonder what the various BusyBox installers do

Busybox (by Stericson) places the busybox binary into /system/xbin and creates symlink for its applets to its binary under the same directory.

Also, I wonder how Android sets the PATH environment variable. As well, I also wonder whether or not there's a way for me to change that variable and to make my change persist across reboots

I do not know when Android sets up $PATH. However, the shell you're using would most likely be having a configuration file.

  • mksh (MirBSD Korn Shell; the default shell on Android) has a configuration file mkshrc in /system/etc. You can set $PATH there and the change would be persistent across reboots.
  • For bash shell, the configuration file is bashrc located under /system/etc/bash.

It appears that both files are meant for interactive sessions only, so if you attempt to use adb for accessing a Toybox or its symlink which is not placed under /sbin, /vendor/bin, /system/sbin, /system/bin or /system/xbin (the default locations in $PATH), you would receive a "COMMAND: not found" error. This is because the default $PATH would be used instead.

I've not found a solution for this problem yet, but see the comments below this answer.

Anyhow, let's install Toybox for now.


How do I install Toybox on an Android device?

Note: the solution assumes that your Android is rooted, that is setup in PC, and that your device is connected to a PC with USB debugging enabled.

Installation into system partition

No change in $PATH is required if you choose a standard location. Busybox prefers /system/xbin.

  • Remount the system partition in rw mode. If required, see Can't remount /system in rw
  • Copy the toybox binary to /system/xbin/ and give executable permission to it. (The default permissions set for other binaries is rwxr-xr-x.)

    You can do so using chmod

    adb shell su -c "chmod 755  /system/xbin/toybox"
    
  • Create symlinks for various tools accessible by toybox binary. It is up to you how you create them.

    I used a very simple method, but it requires a *nix system

    adb shell toybox | sed 's/\ /\n/g' | head -n -1 | tr -d '\r' | while read line; do adb shell su -c 'ln -sf /system/xbin/toybox "/system/xbin/$line"'; done
    

    All I'm doing here is executing the toybox binary, replacing the white-spaces with a new line so that each tool shows up in a new line. Later on I'm removing the last line (it was blank in output), removing carriage return conveniently put by adb, and then for each line of output I'm creating a symlink to toybox binary with the name of the tool, in the same directory.

    You can use this method if you don't have a *nix OS in PC:

    adb shell
    su
    toybox | toybox sed 's/\ /\n/g'| toybox sed '$d'| while read line; do  toybox ln -sf /system/xbin/toybox /system/xbin/$line; done
    

Done! Your Toybox and its applets are ready to be executed.

Installation into data partition

  1. Create a directory under /data (/data/my_bin henceforth)
  2. Copy the toybox binary to /data/my_bin and give executable permission to it. (The default permissions set for other binaries is rwxr-xr-x.)

    adb shell su -c "chmod 755  /system/xbin/toybox"
    
  3. Create symlinks for various tools accessible by toybox binary. It is up to you how you create them.

    I used a very simple method, but it requires a *nix system

    adb shell su -c "/data/my_bin/toybox" | sed 's/\ /\n/g' | head -n -1| tr -d '\r'| while read line; do adb shell su -c "ln -sf /data/my_bin/toybox '/data/my_bin/$line'"; done
    

    Only the location has changed, the rest of the procedure is alike to one followed for installation in system partition

  4. Edit your default shell's configuration file and add

    PATH=/data/my_bin:$PATH 
    

    This would cause the shell to look into /data/my_bin first and execute the binary, if available.

Done! Enjoy your Toybox and its applets.

3
  • I've now posted my own answer, which builds upon yours. If you like it, please upvote it. :) Dec 10, 2015 at 21:37
  • Nope, I don't like it because it doesn't solve my problem and doesn't tell me anything new. I want toybox inside /data or /sdcard but wants non-interactive shells to know about those locations. There should be a hack somewhere. Anyhow, could you cleanup your comments?
    – Firelord
    Dec 11, 2015 at 7:37
  • 1. I've cleaned up my comments. Next time, you can simply flag them as obsolete instead. 2. If you need a hack, perhaps you could recompile mksh and hardcode more paths into it. But anyway, what's wrong with keeping Toybox in /system? Aug 26, 2016 at 16:13
0

If your Android version ships with Toybox and some Toybox symlinks, you can leave those in /system/bin. But, if you're installing Toybox yourself, it might be wisest to put the freshly-installed Toybox, and all its symlinks, in /system/xbin.

Let me explain why.

As Firelord points out in his answer: adb shell starts an interactive shell. But commands such as adb shell ls start a non-interactive shell. For performance reasons, non-interactive shells never read any config files. Because they don't read any config files, their search path is hardcoded.

It's nice to have Toybox available even to non-interactive shells; in fact, if it's unavailable to such shells, it can be confusing. So you definitely want to install Toybox to a location which is on the search path.

But you might not want to put the Toybox symlinks any earlier in the search path than Android's cp, ls, and other basic utilities. I've never checked, but I theorize that your version of Android might include apps which depend on quirks of the stock Android command-line utilities. To learn more, see this post, in which the Android command-line tools maintainer explains why Android had to stick with its non-Toybox ls for some months.

Most of the stock Android command-line utilities are in /system/bin. The only directory which falls later in the stock Android shell's search path is /system/xbin.

That is why you may want to put Toybox and all its symlinks in /system/xbin.


Tip: If you want, you can create a shell script which simply passes all of its parameters to Toybox. You can give this shell script an ultra-short name such as t. This makes it easier to request that your device should run a Toybox toy instead of a stock Android command. For example, to run Toybox ls, simply enter t ls.

3
  • 1
    Tip: you don't need a script actually. A symlink to toybox or renaming the toybox to t would be enough.
    – Firelord
    Dec 11, 2015 at 7:29
  • @Firelord: Neither of those ideas work. If you try them, the Toybox multiplexer simply complains that there is no toy named t. Dec 14, 2015 at 1:07
  • Hmm, that's weird. I'll have to search a reason for the issue. Anyhow, an alias works. I created an alias named t inside mkshrc and it works. alias t="/system/xbin/toybox". You will have to re-read the source file mkshrc using source /system/etc/mkshrc or exit the shell and open a new shell session after making changes.
    – Firelord
    Dec 14, 2015 at 8:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .