Вопрос или проблема
Я только что столкнулся с странным поведением:
echo test>/data/local/tmp/test.txt
su root -c "tar -cvzf /data/local/tmp/test.tar.gz /data/local/tmp/test.txt && echo $?"
ls -alh /data/local/tmp/test.txt
Это создаст пустой test.tar.gz:
removing leading "https://unix.stackexchange.com/" from member names
data/local/tmp/test.txt
0
-rw-r--r-- 1 root root 0 2025-01-09 17:43 /data/local/tmp/test.tar.gz
Запуская без su root -c
, я получу tar.gz размером 120 байт:
-rw-r--r-- 1 root root 120 2025-01-09 17:47 /data/local/tmp/test.tar.gz
Добавление задержки выглядит так:
su root -c "tar -cvzf /data/local/tmp/test.tar.gz /data/local/tmp/test.txt && sleep 1"
Также создает tar.gz размером 120 байт.
То же поведение происходит при использовании другого пользователя, кроме root.
Эта проблема возникает на эмуляторе Android 11. Я не смог воспроизвести это на моих серверах Linux.
Может кто-нибудь объяснить, что здесь происходит, и как убедиться, что tar завершает сжатие?
Ответ или решение
Как IT-специалист, давайте подробно разберем проблему создания пустого tar-файла в контексте использования команды su root -c
на эмуляторе Android 11.
Анализ проблемы
Ваш код создает пустой архив test.tar.gz
, когда команда выполняется с использованием su root -c
. Однако без su root -c
создается архив соответствующего размера. Также добавление задержки (sleep 1
) решает проблему. Этот феномен не наблюдается на обычных серверах Linux, что указывает на специфику окружения Android.
Возможные причины
-
Окружение процесса: Когда вы выполняете команду через
su root -c
, создается новый процесс, который может быть изолированным или функционировать с другим контекстом, отличным от обычной сессии под root. Взаимодействие между временем выполненияtar
и функцией завершения команды с использованием&&
может также обуславливать неожиданные результаты. -
Асинхронность выполнения: Эмуляторы андроида иногда могут демонстрировать некорректное поведение из-за особенностей работы с системными вызовами. Команда
tar
может не успевать завершиться до выхода из сессии, начатойsu
. -
Кеширование или файловая система: Эмулятор может использовать специфические настройки файловой системы, которые влияют на доступные методы обработки файлов или кеширования, что может объяснить нестабильное поведение.
-
Обработка переменных окружения: Использование переменной
$?
в цепочке команд может не обеспечивать полный вывод командыtar
, когда она выполняется в новом окружении, что может мешать корректной диагностике и завершению процесса.
Решения
-
Явное ожидание завершения: Добавление задержки (
sleep 1
) предполагает, что проблема связана с тем, что процессtar
может не успевать завершиться. Это временное решение, и не полностью надежное. -
Использование скриптов: Оберните вашу команду в скрипт, который вызывать с правами root:
#!/bin/sh tar -cvzf /data/local/tmp/test.tar.gz /data/local/tmp/test.txt
Вы можете потом выполнить скрипт через
su root -c "/path/to/script.sh"
. -
Явное управление сессией: Пытаться управлять процессами и их окружением более явно, возможно, предоставив дополнительные временные задержки или проверку до и после выполнения главной команды.
Заключение
Проблема заключается в особенностях работы командной оболочки и системных вызовов на платформе Android внутри эмулятора. Для обеспечения корректной работы более надежным решением будет использование скриптов и управление временем выполнения процессов. Такая стратегия позволяет избегать неопределенного поведения, связанного с конкурентностью процессов и изоляцией окружения.
Если у вас продолжаются затруднения или требуется детальная диагностика, можно рассмотреть подробное логирование процессов для выявления точного поведения системы при выполнении команд.