How to write to removable micro SD card?

On my Teracube 2e (emerald) with /e/OS installed by hand (from Murena), I can’t find a way for shell processes to write to the removable micro SD card: they can only write to /sdcard as emulated from the internal storage. Only apps and adb push seem to be able to write to the filesystem created for the card.

I wanted to air this on the forum because of the privacy focus of the user base here. I have file, music and video collections which exist outside of any app, and the best way to make them available on the phone is to rsync them with an SSH app. However not even adb shell can write there:

$ adb shell
emerald:/ $ df /storage/5*
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/fuse 249810304 95136 249715168 1% /storage/5D04-1F04
emerald:/ $ touch /storage/5D04-1F04/foofile
touch: '/storage/5D04-1F04/foofile': Read-only file system
1|emerald:/ $ exit

$ adb root
restarting adbd as root
$ adb shell
emerald:/ # touch /storage/5D04-1F04/foofile
touch: '/storage/5D04-1F04/foofile': Read-only file system

(For those who haven’t seen this before: note that changing conventional UNIX file modes or using the remount option for mount doesn’t fix it, and that the card has stored plenty of application data from disk-intensive apps like maps & messaging.)

I realise this problem has some history (e.g. Universal way to write to external SD card on Android), but because the Teracube is my first phone whose removable micro SD card is larger that its internal storage, this is the first time I’ve run into it.

I’d be willing to root the phone to solve this problem but I’d be reluctant: there is a somewhat understandable theme in the documentation (for example) to discourage rooting. In fact I chose /e/OS because, after many years of rooting phones, I thought I’d found a secure and stable platform that wouldn’t require it. I’ve installed Magisk on LineageOS phones and can see why it would be discouraged for the different architecture of /e/OS on the Teracube.

So for 2 reasons I wanted to check with the forum, before I try rooting with Magisk, to be sure (with respect to /e/OS particularly):

  1. that there isn’t some simpler means that can open up writing the removable micro SD card to non-application (shell) processes;
  2. that rooting (or some option available through Magisk) can actually fix this problem.
1 Like

I can’t find a way for shell processes to write to the removable micro SD card

it should be available at /mnt/media_rw/… - the /sdcard path is internal storage “home folder” for historical reasons

What else do you want to achieve, efficient sync from pc to sdcard without pushing file again? There is https://github.com/SelfAdjointOperator/better-adb-sync

1 Like

I would have expected that I could rsync stuff to the SD card of my device, so I was interested to test your findings. I am using a Q build, but …

$ ./adb shell
a3xeltexx:/ $ mkdir /storage/809B-16F1/foobar3                                 
a3xeltexx:/ $ touch /storage/809B-16F1/foobar3/foobar4                         
a3xeltexx:/ $ 
  • 1.6-q-20221204240086-dev-a3xelte – unrooted

Maybe it is significant ?

a3xeltexx:/ $ df /storage/809B-16F1/                                           
Filesystem              1K-blocks     Used Available Use% 
/mnt/media_rw/809B-16F1  31158272 27710304   3447968  89%
1 Like

Yes: it looks like it should be, and thanks for that reference, which I knew nothing about & haven’t seen anywhere else. But no, it is not “available” to the shell user:

$ adb unroot
restarting adbd as non root
$ adb shell
emerald:/ $ cd /mnt
emerald:/mnt $ ls -l
total 0
drwxr-x--- 3 root   media_rw  60 2023-01-01 14:43 androidwritable
drwx--x--x 2 root   root      40 2023-01-01 14:43 appfuse
d????????? ? ?      ?          ?                ? asec
d--------- 2 system system    40 2023-01-01 14:43 cd-rom
drwxrwx--x 2 system system    40 2023-01-01 14:43 expand
drwxr-x--- 3 root   media_rw  60 2023-01-01 14:43 installer
d????????? ? ?      ?          ?                ? media_rw
drwxr-xr-x 2 root   system    40 2023-01-01 14:43 obb
d????????? ? ?      ?          ?                ? pass_through
d????????? ? ?      ?          ?                ? product
drwx------ 6 root   root     120 2023-01-01 14:43 runtime
l????????? ? ?      ?          ?                ? sdcard -> ?
drwx------ 3 root   root      60 2023-01-01 14:43 secure
drwxr-x--- 3 root   media_rw  60 2023-01-01 14:43 user
d????????? ? ?      ?          ?                ? vendor
emerald:/mnt $ cd media_rw
/system/bin/sh: cd: /mnt/media_rw: Permission denied
2|emerald:/mnt $ ls media_rw
ls: media_rw: Permission denied

It is more accessible as root but still can’t create files there: it sometimes works but then the files don’t show up on directory listing (there are too many odd results to include all of them here). Whatever is at this mount point, it’s not a “normal” filesystem and doesn’t behave like implementations of fuse that I’ve seen. Here’s one round:

26:matangi$ adb root
restarting adbd as root
27:matangi$ adb shell
emerald:/ # cd /mnt
emerald:/mnt # ls -l
drwxr-x--- 3 root   media_rw          60 2023-01-01 14:43 androidwritable
drwx--x--x 2 root   root              40 2023-01-01 14:43 appfuse
drwxr-xr-x 2 root   system            40 2023-01-01 14:43 asec
d--------- 2 system system            40 2023-01-01 14:43 cd-rom
drwxrwx--x 2 system system            40 2023-01-01 14:43 expand
drwxr-x--- 3 root   media_rw          60 2023-01-01 14:43 installer
drwxr-x--- 4 root   external_storage  80 2023-01-02 15:35 media_rw
drwxr-xr-x 2 root   system            40 2023-01-01 14:43 obb
drwx------ 3 root   root              60 2023-01-01 14:43 pass_through
drwxr-xr-x 2 root   root              40 2023-01-01 14:43 product
drwx------ 6 root   root             120 2023-01-01 14:43 runtime
lrwxrwxrwx 1 root   root              21 2023-01-01 14:43 sdcard -> /storage/self/primary
drwx------ 3 root   root              60 2023-01-01 14:43 secure
drwxr-x--- 3 root   media_rw          60 2023-01-01 14:43 user
drwxr-xr-x 8 root   root             160 2023-01-01 14:43 vendor
emerald:/mnt/media_rw/5D04-1F04 # mkdir foodir
mkdir: 'foodir': File exists
/* ('foodir' was created as a directory in a previous test & doesn't even show up in 'ls'  */
1|emerald:/mnt/media_rw/5D04-1F04 # mkdir Test
mkdir: 'Test': I/O error
1|emerald:/mnt/media_rw/5D04-1F04 # cd Music
emerald:/mnt/media_rw/5D04-1F04/Music # mkdir Test
mkdir: 'Test': Read-only file system

The subdirectories androidwritable and user sound promising but neither of them are accessible either (nor can the shell user access them), including even stranger results:

emerald:/mnt/user/0/5D04-1F04 # touch foofile
emerald:/mnt/user/0/5D04-1F04 # ls -l
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 Alarms
drwxrwx--- 4 root everybody 32768 2022-11-24 19:41 Android
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 Audiobooks
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 DCIM
drwxrwx--- 2 root everybody 32768 2023-01-02 15:37 Documents
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 Download
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 LOST.DIR
drwxrwx--- 3 root everybody 32768 2022-08-07 23:30 Movies
drwxrwx--- 3 root everybody 32768 2023-01-01 14:43 Music
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 Notifications
drwxrwx--- 3 root everybody 32768 2022-08-07 23:30 Pictures
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 Podcasts
drwxrwx--- 2 root everybody 32768 2022-08-07 23:30 Ringtones
 /* (it's not there) */
emerald:/mnt/user/0/5D04-1F04 # rm foofile
rm: foofile: Math result not representable
/* ???!!! */

We are back to my original question then: how does a shell user write to the SD card? Maybe some details from someone who has done it? Some further detail:

thanks: generally helpful to know it works there, but the above is on the R dev build. As reported in the link in the OP, Google has long been locking down these things progressively in successive Android versions. How has the /e/OS team responded to that? :pray: (at least with some workarounds I hope)

I hate having to repeat this but I need a shell user to write to the SD card. The phone supports memory cards, users, and SSH… and there’s no reason why we shouldn’t be allowed to write to the removable SD card. I won’t accept Google’s obvious pressure to herd all people’s personal data into application management. I’m grateful to know about better-adb-sync but it’s outside the scope of this question.

how does a shell user write to the SD card?

is it possible you have the uid/gid ownership of the external sdcard filesystem on something the target device just can’t handle? I’d guess if you let the android device format it you’ll be fine

That makes sense as a guess but doesn’t fit what I reported in the OP: the Android apps are writing to it (maps and messaging apps have created directory structures [in /Android] on the removable SD card). And as I summarised above, even the root user can’t change the uid/gid of files or even their permission modes: so these couldn’t have been set wrong in the first place.

And yes, it was formatted by Android: though in an earlier version of /e/OS. In fact I’ve observed all this behaviour with /e/OS defaults. Therefore I’d be willing to format the removable SD card again… but I’d prefer to wait & give a chance for someone with first-hand experience of this issue to respond. :pray:

@rphair This is probably the only time I wish I wasn"t rooted so I could test this stuff out on my T2e. Well, I probably could temporarily unroot. Not sure.

But anyway, in a root shell I can write to the SDCard via both /mnt/media_rw/ and /storage/[UUID]/.
If all else fails you may have no choice but to root but I feel, as you do that something’s not right.

Searching for this produced some quite old discussions. Apparently this is a long-standing thing.

[Q] ADB shell privileges can’t write to SD card | XDA Forums from 2013.

Cannot write to external SD card · Issue #20 · termux/termux-app · GitHub Termux-related really.

Just spent a lot of time searching and not really finding anything relevant or current for this topic.

1 Like

thanks @marcdw … I’ll give it a week for any more responses & then try (in order)

  1. reformatting the removable SD card, first from within the Android menus if possible, and then maybe with the format command if the shell has one & if it’s accessible by an ordinary user;
  2. if no joy, then rooting. From your writing elsewhere on the forum I’d guess you’re also on the Android R dev version, so your experience is encouraging. Also Magisk after rooting may offer a “systemless” approach to accessing the device without the Android imposed restrictions.

Hoping for more responses in the meantime & will post my further experience here in any case :nerd_face:

1 Like

thanking again all responders above for their help, a couple more notes for others that may be following this:

1 - So as not to over-specify the problem, and because some references by Internet search suggest that adb itself is able to do things that the adb shell user cannot: note that adb push also cannot write to the removable SD card filesystem, counter to what I first wrote above:

$ adb push testfile /storage/5D04-1F04
adb: error: failed to copy 'testfile' to '/storage/5D04-1F04/testfile':
    remote couldn't create file: Read-only file system
testfile: 0 files pushed, 0 skipped. 0.0 MB/s (12 bytes in 0.048s)

2 - better-adb-sync, suggested above, is just a wrapper for the adb utility and therefore can’t do anything any file operations that adb push cannot do.

Note to moderators: I’ll be posting again once I can test after rooting, but this can’t be until I get proper broadband to replace the 4G Internet I have from that phone, probably later this month… so please leave this thread open in the meantime :pray:

while it’s wrapping, It really is comparing trees by itself… but has a (timestamp compare?) bug that makes trees to delete and re-transfer… wasn’t a good recommendation in its current form

This bug demonstrates the reason why I determined that rsync via SSH was the only reliable way to sync computer files to the mobile device. If the problem is in fact the time resolution on Android, we found we could correct for it with the option:

--modify-window=1