- How can I make a symlink (or equivalent) inside /storage/emulated/0?
- EDIT: solution found
- Option 1: symlink
- Option 2: mount
- Option 3: symlink in /data/media/
- My thoughts
- 2 Answers 2
- Symbolic link (symlink) with rooted Android 10
- Breadcrumb
- peppe1996
- jwoegerbauer
- peppe1996
- jwoegerbauer
- peppe1996
- jwoegerbauer
- peppe1996
- Radiolaria
- Что такое симлинки и как их использовать?
- Симлинк
- Как создать симлинк
- На Linux и macOS
- На Windows
- How to add a linked source folder in Android Studio?
- 6 Answers 6
- What is symlink android
How can I make a symlink (or equivalent) inside /storage/emulated/0?
So, I have rooted my phone (GT-i9505 with android 5.0.1) and I would like to move my WhatsApp folder to my external SD card to save 3GB on internal storage. This is what I tried so far.
EDIT: solution found
So, after all the option #2 seemed to be the right one, but it needed some tweaks to make it work. As suggested by Irfan Latif , the problem was that the mount point has to be created in a global mount namespace, otherwise other apps will not see it, so the commands to use are:
But that may not be enough! It still didn’t work until I made sure that the namespace of root was global. To do that I don’t know any universal way, but what worked for me was going in the SuperSU app settings and uncheck the option mount namespace separation .
That really depends on the SU app that you have installed.
Option 1: symlink
The first thing that I thought was to make a symlink, so that was the command that I used:
I had already created a second partition on my external SD card (ext4) that is mounted in /data/sdext2
However that returns operation not permitted when using the terminal emulator (yes I did su ) and an error with any root file manager app that I tried.
After some research I figured out that for some reason, although /storage/emulator/0 is in an ext partition, it is treated in a differente way so that it doesn’t support symlink inside (correct me if I’m wrong).
So, onto the next thing
Option 2: mount
According to this question, the following command should mount the folder on external SD card in another folder in the internal SD card, without the need for a symlink
However, while running the command doesn’t return any error the folder in /sdcard/WhatsApp/Media is still empty, so I don’t really know how to handle this.
Option 3: symlink in /data/media/
I followed the instructions on this post and made the symlink in /data/media/0 instead of storage, so using this command:
This time the link is created! However .
Although an ls in /data/media/0/WhatsApp/Media revealed that the link was successful, cd /sdcard/WhatsApp/Media returns a very irritating no such file or directory and that is confirmed by the file explorer that shows an empty folder with a blank file icon.
My thoughts
First of all, I now discovered that I really hate android. Now, stated this, here’s what I think might help doing:
- moving my sdcard files somewhere else: if the rest of the root filesystem supports symlink (which it seems like it does), I might even move the folder /storage/emulated/0 somewhere else and make a new link to it, but I don’t know if that would solve the problem
That’s it for now, I will update with more options when I think about them.
2 Answers 2
ANDROID STORAGE:
>S> for symlink, >E> for emulated and >B> for bind mount
In short, /sdcard points to /data/media/0 through FUSE or sdcardfs emulation. This is to restrict unauthorized access of apps/processes to private media on SD card. Read Android’s Storage Journey.
SYMLINKS:
Now /sdcard is not a real but emulated storage which represents a FAT/vFAT/FAT32 filesystem (for backward compatibility and permission management) which doesn’t support symlinks (and other things including *NIX permissions and ioctls like FS_IOC_FIEMAP ). So the Option 1 and 3 of yours won’t work whether you create symlink directly on emulated storage or try to emulate the symlink already created on ext4.
BIND MOUNT:
This is the commonly used alternate of symlink for FAT family of filesystems. What you have tried in Option 2 should work. This is what apps like Apps2SD do. But there is again a constraint: mount namespace . You need to bind mount in global/root mount namespace so that the mount is visible to all apps:
On Android 6+ this needs to be bind mounted on each VIEW (default, read, write) separately for all apps to work.
You can make it permanent by setting Mount Namespace Mode to Global in Magisk or by disabling Mount Namespace Separation in SuperSU. For details see this answer.
Источник
Symbolic link (symlink) with rooted Android 10
Breadcrumb
peppe1996
Senior Member
jwoegerbauer
Senior Member
When you download a photo from within the Facebook app, it is stored in DCIM/Facebook. When you launch the Gallery app, the image shows up right under «Photos». Also in the gallery app if you click on the «COLLECTIONS» tab, it shows up there under «Camera».
FYI: Creating a symlink basically doesn’t require Android is got rooted, unless you want to create symlinks in Android’s /system partition.
I think it’s really easy to create symlinks on Android.
Example:
peppe1996
Senior Member
When you download a photo from within the Facebook app, it is stored in DCIM/Facebook. When you launch the Gallery app, the image shows up right under «Photos». Also in the gallery app if you click on the «COLLECTIONS» tab, it shows up there under «Camera».
FYI: Creating a symlink basically doesn’t require Android is got rooted, unless you want to create symlinks in Android’s /system partition.
I think it’s really easy to create symlinks on Android.
Example:
jwoegerbauer
Senior Member
My fault was to NOT tell you that symlinks only are possible on partitions that support it, means their filesystem is either ext2 or ext3 or ext4 or yaffs2.
Internal sdcard /storage/emulated/0 where folder DCIM resides has filesystem /dev/fuse. Hence my script example was totally wrong.
peppe1996
Senior Member
My fault was to NOT tell you that symlinks only are possible on partitions that support it, means their filesystem is either ext2 or ext3 or ext4 or yaffs2.
Internal sdcard /storage/emulated/0 where folder DCIM resides has filesystem /dev/fuse. Hence my script example was totally wrong.
jwoegerbauer
Senior Member
IMHO an alternative is to create a so-called bind mount. A bind mount is an alternate view of a directory tree. Classically, mounting creates a view of a storage device as a directory tree. A bind mount instead takes an existing directory tree and replicates it under a different point. The directories and files in the bind mount are the same as the original. Any modification on one side is immediately reflected on the other side, since the two views show the same data.
Example pseudo code:
In your case this should problemfree work because both /sdcard/DCIM/Facebook and /sdcard/Pictures have the same filesystem.
FYI: mount command by default is available in any Android version.
IMPORTANT: Such a bind mount isn’t persistent: you have to get it created everytime when Android boots up. That in turn requires to have an init.d script what does the job.
peppe1996
Senior Member
IMHO an alternative is to create a so-called bind mount. A bind mount is an alternate view of a directory tree. Classically, mounting creates a view of a storage device as a directory tree. A bind mount instead takes an existing directory tree and replicates it under a different point. The directories and files in the bind mount are the same as the original. Any modification on one side is immediately reflected on the other side, since the two views show the same data.
Example pseudo code:
In your case this should problemfree work because both /sdcard/DCIM/Facebook and /sdcard/Pictures have the same filesystem.
FYI: mount command by default is available in any Android version.
IMPORTANT: Such a bind mount isn’t persistent: you have to get it created everytime when Android boots up. That in turn requires to have an init.d script what does the job.
Radiolaria
Member
IMHO an alternative is to create a so-called bind mount. A bind mount is an alternate view of a directory tree. Classically, mounting creates a view of a storage device as a directory tree. A bind mount instead takes an existing directory tree and replicates it under a different point. The directories and files in the bind mount are the same as the original. Any modification on one side is immediately reflected on the other side, since the two views show the same data.
Example pseudo code:
Code:
mount -o bind /some/where /else/where
In your case this should problemfree work because both /sdcard/DCIM/Facebook and /sdcard/Pictures have the same filesystem.
FYI: mount command by default is available in any Android version.
IMPORTANT: Such a bind mount isn’t persistent: you have to get it created everytime when Android boots up. That in turn requires to have an init.d script what does the job.
Hello, i just bring this here up again because i have a similar problem.
I tryed your command and it passed without errors. But without the wished effect.
The last line appears after i try to mount the folder. Does anybody k ow what goes wrong here?
Источник
Что такое симлинки и как их использовать?
Как пользователь компьютера, вы точно сможете сказать, что такое ярлык. Это некий указатель на файл, папку или приложение, так ведь? В целом да, но есть ли другие способы создать указатель на файл и можно ли заставить систему думать, что файл находится совсем в другом месте? На эти вопросы мы постараемся ответить в данной статье.
Симлинк
Симлинк или символическая ссылка похожа на обычный ярлык, но на деле это не то же самое, что ярлык на рабочем столе. С помощью обычного ярлыка вы можете просто открыть файл, который находится совсем в другом месте, а симлинк привязывает этот файл к новому месту, по сути, создавая иллюзию того, что файл находится там, куда указывает симлинк. Звучит сложно? На деле – проще некуда.
Для примера возьмем случай с установкой в компьютер нового, очень быстрого SSD. Вот вы заново установили ОС на новый диск, а все файлы остались на старом, и вместо того, чтобы заново скачивать и устанавливать “тяжелые” программы и игры вы можете просто создать симлинки. То есть, создать видимость присутствия старых файлов на новом месте, без их фактического перемещения.
Как создать симлинк
На Linux и macOS
На Linux вы можете создать символьную ссылку на файл или папку простой консольной командой:
ln -s [/путь/к/файлу] [/путь/к/ссылке]
Поскольку macOS является UNIX-подобной системой, то и команда для создания симлинка отличаться не будет. Стоит отметить, что некоторые файловые менеджеры позволяют создавать симлинки через собственный интерфейс.
На Windows
Для устройств на базе ОС Windows команда будет слегка отличаться для того, чтобы создать симлинк к файлу необходимая строка будет выглядеть:
mklink [/путь/к/файлу] [/путь/к/ссылке]
Для того, чтобы создать симлинк к папке, вам придется добавить флаг /d
mklink /d [/path/to/symlink] [/path/to/file]
Источник
How to add a linked source folder in Android Studio?
In Eclipse I can add a source folder to my android project as a «linked source folder». How do I achieve the same thing in Android Studio?
Or is it possible to add a external folder to build in gradle?
6 Answers 6
in your build.gradle add the following to the end of the android node
The right answer is:
Furthermore, if your external source directory is not under src/main , you could use a relative path like this:
You can add a source folder to the build script and then sync. Look for sourceSets in the documentation here: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Basic-Project
I haven’t found a good way of adding test source folders. I have manually added the source to the .iml file. Of course this means it will go away everytime the build script is synched.
While sourceSets allows you to include entire directory structures, there’s no way to exclude parts of it in Android Studio (as of version 1.2), as described here: Android Studio Exclude Class from build?
Until Android Studio gets updated to support include/exclude directives for Android sources, Symlinks work quite well. If you’re using Windows, native tools such as junction or mklink can accomplish the equivalent of Un*x symlinks. CygWin can also create these with a little coersion. See: Git Symlinks in Windows and How to make symbolic link with cygwin in Windows 7
Just in case anyone is interested, heres a complete Java module gradle file that correctly generates and references the built artefacts within an Android multi module application
If you’re not using gradle (creating a project from an APK, for instance), this can be done through the Android Studio UI (as of version 3.3.2):
- Right-click the project root directory, pick Open Module Settings
- Hit the + Add Content Root button (center right)
- Add your path and hit OK
In my experience (with native code), as long as your .so ‘s are built with debug symbols and from the same absolute paths, breakpoints added in source files will be automatically recognized.
Источник
What is symlink android
FAQ по созданию патча update.zip для прошивки через рекавери
Редактирование Updater-script. Информация, решения, команды, подпись патчей.
Инструкция по установке системных и пользовательских приложений с помощью recovery
Редактирование установленной прошивки и удаление системных приложений
(ключевые слова)
Напоминаю, тут не стол заказов.. Посты с просьбой собрать zip для «хххх» Recovery оффтоп
Сообщения, не относящиеся к теме обсуждения (оффтоп), удаляются без предупреждения
- Добавление нескольких пользовательских/системных приложений «за один клик» (одним патчем).
- Добавление/удаление системных приложений без root прав и вспомогательных программ.
- Изменение прошивки (замена файлов, украшательства и т.д.).
- Обновление программы или прошивки.
- Переразметка памяти (обсуждения в другой теме)
- Получение root прав SuperUser, SuperSU, Magisk
- Установленный на телефоне кастомный рекавери (CWM/TWRP)
- NotePad++ (редактор с сохранением Unix формата)
- Zip_signer (подписчик архивов)
- Архиватор ZIP
- Файл-заготовка sample.zip (либо update-binary для ручной сборки)
Zip_signer.rar ( 13.28 КБ )
sample-patch.rar ( 4.77 МБ )
update-binary.rar ( 113.25 КБ )
- Дополнительные версии бинарника.
binary_all.rar ( 649.36 КБ )
- Бинарники (архив/исходники)
Исходники бинарника, основная ссылка:
https://android.google…ootable/recovery/+refs
выбираем к примеру «android-9.0.0_r18» , потом ищем папку «updater», в папке «updater» исходники бинарника
К примеру https://android.google…droid-9.0.0_r18/updater — можно глянуть все команды которые может выполнить бинари в андроид 9.0.0 (в файле install.cpp, в самом низу)
+ Android update-script (Пост Няшная #63580419)
Внимание! Патчи создаются только для мод.рекавери и результативно работают только в них. В стоковых рекавери (на аппаратах «из коробки») патчи не работают.
Для того, чтобы установить новые системные приложения apk в Ваш аппарат, необходимо выполнить три шага:
- Собрать свой update.zip (из заготовки sample.zip)
- Подписать update.zip утилитой Zip_signer(Не обязательно!)
- Закинуть на флэшку и установить в аппарат через ClockWorkMod Recovery
Эти шаги являются универсальными, т.е. подойдут для выполнения других подобных операций.
ШАГ №1
Собрать новый update.zip, используя «болванку» sample.zip
Порядок использования sample.zip:
- Разархивировать архив sample.zip
- Удалить файлы подписи META-INF/CERT.RSA, CERT.SF, MANIFEST.MF (т.к. 2м шагом мы их будем создавать для своей сборки)
- Поместить в папку /data/app свое пользовательское приложение (xxxxx.apk)
- При необходимости отредактировать файл updater-script (подробнее позже)
- Заархивировать всё (META-INF и data) ZIP’ом без сжатия
ШАГ №2
Подписать update.zip с помощью утилиты Zip_signer
Порядок использования утилиты Zip_signer:
- Переименовать Ваш отредактированный (т.е. уже с приложением внутри) sample.zip в update.zip
- Поместить его в папку с программой Zip_signer
- Запустить файл zip_signer.bat
- Дождаться, пока процесс будет завершен
- В папке появится файл update-finished.zip — это и есть подписанный файл
- Переименовать update-finished.zip по своему усмотрению (согласно логике патча)
ШАГ №3
Установка нового приложения
- Перекинуть (переименованный) update-finished.zip на флэшку и установить его в аппарат через TWRP или CWM (install zip from sdcard -> chooze zip from internal sdcard -> Yes, install sample.zip)
- Перезагрузить аппарат
/ )
Внимание! Патчи создаются только для мод.рекавери и результативно работают только в них. В стоковых рекавери (на аппаратах «из коробки») патчи не работают.
Корень патча:
- папка META-INF
- папка источник установки приложений (system, data, sdcard, cache, sd-ext)
Обязательные файлы: - META-INF/com/google/android/update-binary — системное средство запуска данного патча, также создает временную рабочую папку tmp
- META-INF/com/google/android/updater-script — выполняемый скрипт по которому и происходят операции копирования и т.д.
Разберем sample.zip
Патч добавляет пользовательское приложение MyPiano в Data.
— Выводит сообщение о завершении процесса.
- busybox — приложение для выполнения командной строки, устанавливается с кастомным рекавери, находится в ramdisk/sbin. в кастомных прошивках зачастую добавляют его в system/xbin
Возможные исправления для своих целей
- Изменение прав
• package_extract_dir
Синтаксис: package_extract_dir(» «, » «);
Копирует содержимое в . Файлы в имеющиеся в перезаписываются.
Пример: package_extract_dir(«system», «/system»); Скопирует файлы из папки update.zip/system в /system
• package_extract_file
Синтаксис: package_extract_file(» «, » «);
Копирует файл в . Если файл существует, то он перезаписывается.
Пример: package_extract_file(«test.sh», «/tmp/test.sh»); Скопирует файл test.sh из update.zip в /tmp/test.sh
• format
Синтаксис: format(«MTD», » «);
Форматирует раздел (см. приложение).
Пример: format(«MTD», «system»); Полностью отформатирует /system . Примечание: форматирование удаляет данные необратимо.
Пример 2: format(«ext4», «EMMC», «/dev/block/mtdblock5», «0», «/system»);
Определение номера блока под спойлером «инфо и материалы».
• delete
Синтаксис: delete(» «[, «file2», . «fileN»]);
Удаляет файл(ы)
Пример: delete(«/system/app/Calculator.apk»); Удалит Calculator.apk из папки system/app.
• delete_recursive
Синтаксис: delete_recursive(» «[, «dir2», . «dirN»]);
Рекурсивно удаляет папку(и) со всем содержимым
Пример: delete_recursive(«/data/dalvik-cache»); Удалит папку /data/dalvik-cache со всем содержимым.
• run_program
Синтаксис: run_program(» «[, » «, » «, » «]);
Запускает программу(скрипт) .
Пример: run_program(«/tmp/install_busybox.sh»); Запустит скрипт /tmp/install_busybox.sh.
«[, . «pathtofileN»]);
Устанавливает владельца, группу и разрешения для файла или папки, как ‘chmod’, ‘chown’, и ‘chgrp’ всё в одном
Пример: set_perm(0, 2000, 0550, «/system/etc/init.goldfish.sh»); Установит владельца, группу и разрешения для файла /system/etc/init.goldfish.sh
• set_perm_recursive
Синтаксис: set_perm_recursive( , , , , «
«])
Рекурсивно устанавливает владельца, группу и разрешения для содержимого папки. — для папок, — для файлов.
Пример: set_perm_recursive(0, 0, 0755, 0644, «/system/app»); Установит права для содержимого /system/app, для папок — 0755, для файлов — 0644.
• show_progress
Синтаксис: show_progress( , );
Продвижение прогрессбара на долю за секунд. может быть нулевым для продвижения его по командe set_progress, а не по времени.
Пример: show_progress(0.100000, 1); Увеличит прогресс на 0.1 часть за 1 секунду
• set_progress
Синтаксис: set_progress( );
Устанавливает положение прогрессбара на долю , для самого последнего вызова команды show_progress.
Пример: set_progress(0.500000);
• symlink
Синтаксис: symlink(«
Создает символическую ссылку (как ‘ln-s’).
Пример: symlink(«/data/app_s», «/system/app»); Создаст символическую ссылку на папку /data/app_s для папки /system/app
«);
Монтирует в путь
. должно быть название раздела, если это «MTD», или блок памяти если это «vfat»
Пример: mount(«MTD», «userdata», «/data»);
• ui_print
Синтаксис: ui_print(» «);
Выводит на экран сообщение
Пример: ui_print(«Formatting SYSTEM. «);
• sleep
Синтаксис: sleep( );
Пауза процесса на секунд
Пример: sleep(5); — пауза 5 секунд, после чего код скрипта выполняется дальше.
• set_metadata / set_metadata_recursive
Синтаксис: set_metadata (. );
Устанавливает владельца, группу и разрешения (новая команда взамен set_perm для andriod 4.4.*)
Примеры: Android update-script (Пост #32151495)
Создание патча update.zip для прошивки через рекавери (Пост kory-vadim #81945464)
• set_metadata / set_metadata_recursive
Синтаксис:
set_metadata(«имя файла», «ключ1», «значение1», «ключ2», «значение2», . )
set_metadata_recursive(«имя директории», «ключ1», «значение1», «ключ2», «значение2», . )
Ключи:
* uid
* gid
* mode (set_perm_extd only)
* fmode (set_perm_extd_recursive only)
* dmode (set_perm_extd_recursive only)
* selabel
* capabilities
первые три (uid, gid, mode) это тоже самое что и в chmod, заполняется «uid», 0, «gid», 1000, «mode», 06754.
для установки прошивки хватает трех ключей «uid», 0, «gid», 1000, «mode», 06754.
Пример: set_metadata(«/system/xbin/shelld», «uid», 0, «gid», 1000, «mode», 06754, «capabilities», 0x0, «selabel», «u:object_r:system_file:s0»);
set_metadata_recursive(«/system/xbin», «uid», 0, «gid», 2000, «dmode», 0755, «fmode», 0755, «capabilities», «0x0», «selabel», «u:object_r:system_file:s0»);
• команды для Nexus’ов
block_image_update(«/dev/block/platform/msm_sdcc.1/by-name/system», package_extract_file(«system.transfer.list»), «system.new.dat», «system.patch.dat»);
Синтаксис: block_image_update(«Путь к блоку раздела», package_extract_file(«список информации для патча (?) «), «образ», «патч образа»);
я так понимаю, что так прошивается сильно сжатая прошивка (образ системы).
Еще ifelse
Пример: ifelse(is_mounted(«/system»), unmount(«/system»)); — если раздел сустем смонтирован дается команда на его размонтирование, если размонтиовать то нечего не происходит.
• Информация по атрибутам set_metadata и подобным командам на Android 4.4+
Android update-script (Пост blackeangel #50803606)
Описание откуда берутся «u:object_r:uncrypt_exec:s0» и подобные атрибуты. . .
• Пример скрипта который может удалять\перемещать\бекапить файлы и вести лог действий
Android Script Creator (Пост Octanium #51085030)
Используется при отсутствии busybox, либо чтоб не привязываться к его расположению в системе.
Код «перезагрузки» и «перезагрузки в рекавери» соответственно:
Когда скрипт выполняется очень быстро (1-4 секунд) я использовал следующий код:
Т.е. за 3 секунды прогресс бар доходит до 100% (постепенно).
Число «3» выбрано как [время установки скрипта]+1 сек, чтоб прогресс бар при установке гарантированно двигался и не успел дойти до 100% раньше, чем скрипт установится.
«[, . «pathtofileN»]);
Устанавливает владельца, группу и разрешения для файла или папки, как ‘chmod’, ‘chown’, и ‘chgrp’ всё в одном
Пример: set_perm(0, 2000, 0550, «/system/etc/init.goldfish.sh») Установит владельца, группу и разрешения для файла /system/etc/init.goldfish.sh
«])
Рекурсивно устанавливает владельца, группу и разрешения для содержимого папки. — для папок, — для файлов.
Пример: set_perm_recursive(0, 0, 0755, 0644, «/system/app») Установит права для содержимого /system/app, для папок — 0755, для файлов — 0644.
«);
Монтирует в путь
. должно быть название раздела, если это «MTD», или блок памяти если это «vfat»
Пример: mount(«MTD», «userdata», «/data»);
Пример монтирования на андроид 9-10
Если Вам знакомо что такое Recovery, CWM,TWRP, знаете что такое кастомные прошивки и с чем их едят, то наверняка вы сталкивались с тем что прошивка или обновление не устанавливается выводя при этом ошибку «Status #».
Источник