簡體   English   中英

使用 run-as 在 ADB shell 中復制文件

[英]Copying files in ADB shell with run-as

有沒有辦法編寫一個腳本,使用 run-as 從 ADB shell 復制文件?

我知道在 adb shell 中復制的唯一方法是使用cat source > dest (編輯:現代 android 版本有cp命令,這使得這個問題不必要),但我只能引用大於號一級深 - 所以我的腳本可以將它傳遞給 adb shell,但不能傳遞給 adb shell run-as。

例如,這有效:

adb shell "cat source > dest"

但這不會:

adb shell run-as "cat source > dest"

也不是這個:

adb shell "run-as cat source \> dest"

我什至嘗試創建一個小腳本並將其上傳到設備,但我似乎無法從 adb shell 運行該腳本 - 它告訴我“權限被拒絕”。 我也不能 chmod 腳本。

我想這樣做的原因是將文件復制到應用程序的私有存儲區域——具體來說,我正在使用腳本來修改共享首選項並將修改后的首選項放回原處。 但是,只有應用程序本身或 root 可以寫入我想要的文件。

此場景中的用例是將文件復制到設備上的受保護位置,而不是檢索它; 對於檢索, 這個問題已經有了很好的答案。

遵循克里斯·斯特拉頓的建議,我最終使它起作用的方式如下(用於將共享首選項復制回設備):

adb push shared_prefs.xml /sdcard/temp_prefs.xml
cat <<EOF | adb shell
run-as com.example.app
cat /sdcard/temp_prefs.xml > /data/data/com.example.app/shared_prefs/com.example.app_preferences.xml
exit
exit
EOF

直接管道到adb shell run-as行不通的,我也不知道為什么,但是管道到adb shell可以。 訣竅是,然后從交互式外殼程序調用運行方式,並繼續接受來自管道的輸入。

這里的文檔使我可以輕松地將換行符嵌入到單獨的命令中,並且通常使它易於閱讀; 我在分號方面運氣不太好,但這可能是因為我做事的方式。 我相信它可以與傳遞多個命令/換行符的其他方法一起使用; 終於讓實驗開始工作后,我就停止了實驗。

這兩個出口對於防止掛殼是必需的(可通過CTRL-C殺死); 一個用於run-as ,另一個用於adb shell本身。 看來,Adb的外殼對文件結束的響應不是很好。

OP嘗試將以下3個命令(他在交互式shell會話中一個接一個地執行沒有問題)組合成一個非交互式命令:

adb shell
run-as com.example.app
cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml

為簡單起見,讓我們從交互式adb shell會話開始。 如果我們只是嘗試將最后兩個命令合並為一行:

run-as com.example.app cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml

由於shell重定向的工作原理,此方法不起作用-僅命令的cat /sdcard/temp_prefs.xml部分將使用com.example.app UID運行

許多人“知道”將圍繞重定向的命令部分放在引號中:

run-as com.example.app "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"

這是行不通的,因為run-as命令不夠智能,無法分析整個命令。 它期望將可執行文件作為下一個參數。 正確的方法是使用sh代替:

run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"

那么,我們可以僅在命令前添加adb shell並使用它嗎? 不必要。 通過從PC運行命令,您還可以添加另一個本地Shell及其解析器。 特定的轉義要求取決於您的操作系統。 在Linux或OSX中(如果您的命令尚未包含任何' ),可以很容易地用單引號將整個命令引起來,如下所示:

adb shell 'run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"'

但是有時使用帶(-或更少)引號的替代解決方案會更容易:

adb shell run-as com.example.app cp /sdcard/temp_prefs.xml shared_prefs/com.example.app_preferences.xml

或者,如果您的設備沒有cp命令:

adb shell run-as com.example.app dd if=/sdcard/temp_prefs.xml of=shared_prefs/com.example.app_preferences.xml

還要注意我是如何使用shared_prefs/com.example.app_preferences.xml而不是完整的/data/data/com.example.app/shared_prefs/com.example.app_preferences.xml -通常在run-as命令內部,當前目錄是您的包裹的HOME目錄。

您可以只更改目錄的權限,然后拉出所有文件。 但是對我來說,我只在尋找一個共享的首選項文件,並且我能夠獲得像這樣的數據:

PACKAGE='com.mypackage.cool'
SHAREDPREF_FILE="${PACKAGE}_preferences.xml"

    adb shell "run-as $PACKAGE cat /data/data/$PACKAGE/shared_prefs/$SHAREDPREF_FILE">$SHAREDPREF_FILE

現在,我們將sharedpreference文件的數據存儲在同名文件中。

使用最新的adb (ADB v1.0.41 / 版本 33.0.3)和 Play Store 模擬器圖像,我遇到了adb root未被授予的情況。 我也無法從/data/local//storage/emulated/0/復制,因為在run-as com.myapp.app時沒有權限

new_prefs_path="my_machine.xml"
config="$(cat $new_prefs_path)"
my_app_uri="com.myapp.app"
adb shell "run-as $my_app_uri sh -c 'echo \"$config\" > shared_prefs/on_android.xml'"

這為我將其修復為 bash 腳本。 由於需要為不同的應用程序和復雜的有效負載進行配置,它變得稍微復雜一些。 我們獲取一個文件(可以在此腳本的前面生成)並將其讀取到一個變量中。 然后我們啟動 shell,執行run-as my app 並運行 echo 將讀取的文件擴展到 shared_prefs 中的文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM