【问题标题】:How to escape a nested ADB shell command in bash如何在 bash 中转义嵌套的 ADB shell 命令
【发布时间】:2021-06-04 18:12:02
【问题描述】:

对于涉及通过 ADB shell 以用户 ceres 身份发出 dconf 命令的 bash 脚本,我需要嵌套多个命令。 以下三个命令的手动顺序执行完美无缺。

adb shell
su ceres
dconf write /desktop/asteroid/watchface "'file:///usr/share/asteroid-launcher/watchfaces/$opt.qml'"

我学会了转义 dconf 关键字以正确地将 dconf 嵌套在 su ceres -c '<command>' 中。

su ceres -c 'dconf write /desktop/asteroid/watchface \"'file:///usr/share/asteroid-launcher/watchfaces/$opt.qml'\"'

如何将上面的命令嵌套和转义到adb shell "<command>"

adb shell "su ceres -c 'dconf write /desktop/asteroid/watchface \"'file:///usr/share/asteroid-launcher/watchfaces/$opt.qml'\"'"

当从 bash 脚本发出时,会导致 dconf 回复 error: 0-4:unknown keyword

感谢您的帮助和解释!

【问题讨论】:

    标签: bash escaping adb su


    【解决方案1】:

    对于极度嵌套的情况,我会坚持使用printf %q,而不是手动进行引用:

    #! /usr/bin/env bash
    printf -v cmd %q "'file:///usr/share/asteroid-launcher/watchfaces/$opt.qml'"
    printf -v cmd %q "dconf write /desktop/asteroid/watchface $cmd"
    adb shell "su ceres -c $cmd"
    

    【讨论】:

    • 太棒了!得到它的工作。感谢您发布确切的命令。刚才查看man printf 以便更好地理解。
    • @TimoKönnecke 当心。有多个printfs。并非所有独立版本(记录在man printf 中)都支持%q,并且没有一个可以支持-v。我的意思是printf 内置在bash 中。你可以在help printf阅读它的文档。
    • 由于脚本可能会有一些用户,我会记住这一点,因为它不适用于某些非 bash 用户。再次感谢你! ADB 转移只是脚本中的可选/备用。大多数用户将使用我可以嵌套工作的 ssh/scp 方法。
    【解决方案2】:

    大概,adb shell 从标准输入读取。您可以使用此处的文档来简化此操作(以及使用sudo 执行adb shell 而不是使用su):

    sudo -u ceres adb shell <<EOF
    dconf write /desktop/asteroid/watchface "file:///usr/share/asteroid-launcher/watchfaces/$opt.qml"
    EOF
    

    如果不是,这可能更简单,

    sudo -u ceres adb shell -c "dconf write /desktop/asteroid/watchface 'file:///usr/share/asteroid-launcher/watchfaces/$opt.qml'"
    

    【讨论】:

    • 我不想在执行脚本的主机上使用 sudo。我假设普通用户可能没有在他们正在执行它的机器上授予 root 权限。目标是拥有一个脚本,将表盘从github.com/AsteroidOS/unofficial-watchfaces 加载到连接的 AsteroidOS 手表,为最终用户增加一点便利。还是谢谢!很高兴学习。
    • PC 上的 sudo 不影响安卓设备。此外,根本没有 sudo
    • 你从来没有提到这是一台 PC。 (虽然我不知道 adb 实际在做什么。)