[英]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.