Чтобы выполнить команду с определенным рабочим каталогом, обычно делают
( 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
Опять же, это неменяет рабочий каталог для команды.
adb
добавляет возврат каретки (он же 0x0d
, Ctrl-M
, \r
и т. д. ) перед переводом строки. Вероятно, для простоты использования программного обеспечения Windows, которое ожидает, что строки заканчиваются на CR-LF, а не только на LF.
Вы можете увидеть это сами с помощью hexdump
aka 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
Другой ответ хорошо объясняет, где ошибся спрашивающий. Мораль этой истории заключается в том, что нужно быть осторожным при подсчете символов, так как adb может их добавить.
Я сделал это
R=$(adb shell 'ls /mnt && echo SUCCESS || echo FAIL' | egrep (SUCCESS|FAIL))
echo $R