Как я могу оценить результат команды оболочки adb?

Чтобы выполнить команду с определенным рабочим каталогом, обычно делают

( cd directory && utility )

Круглые скобки вокруг cd ... означают, что команды в нем выполняются в подоболочка. Изменение рабочего каталога в подоболочке делает так, что текущий рабочий каталог вызывающей оболочки не изменяется, т. е. после вызова этой команды вы все равно будете находиться в том же каталоге, откуда вы начали.

Пример:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

Это нельзя превратить в общий псевдоним, поскольку псевдоним не может принимать никаких аргументов.

Для конкретногокаталога и утилиты можно было бы сделать

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

, но в общем случае вам придется использовать функцию оболочки:

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

или

cdrun () (
    cd "$1" && shift && command "$@"
)

Замена фигурных скобок круглыми скобками вокруг тела функции заставляет функцию выполняться в своей собственной подоболочке.

Это будет использоваться как

$ cdrun "$HOME/somedir" ./script.sh

, который будет запускать скрипт script.sh, расположенный в каталоге $HOME/somedir, с $HOME/somedir. ] в качестве рабочего каталога или

$ cdrun / ls -l

, который предоставит вам список каталогов в «длинном формате» корневого каталога.

Функция оболочки принимает свой первый аргумент и пытается перейти в этот каталог. Если это работает, он смещает имя каталога из позиционных параметров (список аргументов командной строки) и выполняет команду, заданную остальными аргументами. команда— это встроенная в оболочку команда, которая просто выполняет свои аргументы как команду.


Все это нужно, если вы хотите выполнить команду с измененным рабочим каталогом. Если вы просто хотите выполнить команду, расположенную в другом месте, вы, очевидно, можете использовать

alias thing='$HOME/somedir/script.sh'

, но это запустит script.sh, расположенный в $HOME/somedirс currentв качестве рабочего каталога.

Другой способ выполнения скрипта, расположенного в другом месте, без изменения рабочего каталога — добавить местоположение скрипта в переменную окружения PATH, например

PATH="$PATH:$HOME/somedir"

Теперь script.shв $HOME/somedirможно будет запускать откуда угодно, просто используя

$ script.sh

Опять же, это неменяет рабочий каталог для команды.

1
18.08.2017, 01:54
2 ответа

adbдобавляет возврат каретки (он же 0x0d, Ctrl-M, \rи т. д. ) перед переводом строки. Вероятно, для простоты использования программного обеспечения Windows, которое ожидает, что строки заканчиваются на CR-LF, а не только на LF.

Вы можете увидеть это сами с помощью hexdumpaka hd, например.:

$ printf "$R" | hd
00000000  30 0d                                             |0.|
00000002

Потому что вам нужно вернуть только одно значение (код выхода). вы можете использовать printfвместо echoи перенаправить весь вывод lsна /dev/nullна устройстве Android, чтобы избежать печать любых новых строк (тогда adb не добавляет CR):

R="$(adb shell 'ls /mnt/ > /dev/null 2>&1 ; printf $?')"

Если на вашем устройстве Android нет printfили если вам нужно вернуть одну или несколько строк вывода из оболочки Android , вы можете использовать tr -d '\r'или dos2unixили sed 's/\r$//'или подобное, чтобы удалить CR.

dos2unixи sedявляются лучшим выбором, чем trздесь, потому что они удалят только те CR, за которыми сразу следует LF, оставляя нетронутыми любые CR, которые могут быть в другом месте в строка:

$ R="$(adb shell 'ls /mnt/ > /dev/null 2>&1 ; echo $?' | dos2unix)"
$ printf "$R" | hd
00000000  30                                                |0|
00000001
7
27.01.2020, 23:13

Другой ответ хорошо объясняет, где ошибся спрашивающий. Мораль этой истории заключается в том, что нужно быть осторожным при подсчете символов, так как adb может их добавить.

Я сделал это

R=$(adb shell 'ls /mnt && echo SUCCESS || echo FAIL' | egrep (SUCCESS|FAIL))
echo $R
0
27.01.2020, 23:13

Теги

Похожие вопросы