Get result code of adb shell command - android

How should I get $? of adb shell <command>?
I would like to check the result of adb shell mkdir /xxx.
I executed mkdir command by adb shell and failed but the result of $? is 0.
$ adb shell mkdir /xxx
mkdir failed for /xxx, Read-only file system
$ adb shell echo $?
0
$ adb shell "mkdir /xxx; echo $?"
mkdir failed for /xxx, Read-only file system
0
I would like to get the result code of adb shell <command> but not in the interactive mode like below:
$ adb shell
shell#android:/ $ mkdir /xxx
mkdir failed for /xxx, Read-only file system
255|shell#android:/ $ echo $?
255

You should do:
$ adb shell 'mkdir /xxx; echo $?'
mkdir failed for /xxx, Read-only file system
255
Notice the single quotes, otherwise $? is evaluated before reaching adb.

If you are using an older emulator, then adb shell does not return the exit value. Then you have to use adb shell 'false; echo $?' like in https://stackoverflow.com/a/17480194/306864
In newer emulators, it works properly, then you can do adb shell false || echo failed. Here's how I tested:
$ adb -e android-22 shell false; echo $?
0
$ adb -e android-22 shell 'false; echo $?'
1
$ adb -e android-29 shell false; echo $?
1
$ adb -e android-29 shell 'false; echo $?'
1

Related

/system/bin/sh: tr: not found - Android Azure Devops pipeline

I get the following error when I try to start the emulator from my pipeline in Azure:
nohup $ANDROID_HOME/emulator/emulator -avd xamarin_android_emulator -no-snapshot >
/dev/null 2>&1 &
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop
sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
$ANDROID_HOME/platform-tools/adb devices
echo "Emulator started"
Generating script.
##[debug]which 'bash'
##[debug]found: '/bin/bash'
##[debug]Agent.Version=2.204.0
##[debug]agent.tempDirectory=/Users/runner/work/_temp
##[debug]check path : /Users/runner/work/_temp
========================== Starting Command Output ===========================
##[debug]which '/bin/bash'
##[debug]found: '/bin/bash'
##[debug]/bin/bash arg: /Users/runner/work/_temp/52b9227f-faa1-
4557-9396-
8b3c63435983.sh
##[debug]exec tool: /bin/bash
##[debug]arguments:
##[debug] /Users/runner/work/_temp/52b9227f-faa1-4557-9396-
8b3c63435983.sh
/bin/bash /Users/runner/work/_temp/52b9227f-faa1-4557-9396-
8b3c63435983.sh
* daemon not running; starting now at tcp:5037
* daemon started successfully
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
/system/bin/sh: tr: not found
Given below is my pipeline yml
# Android
# Build your Android project with Gradle.
# Add steps that test, sign, and distribute the APK, save build artifacts, and more:
# https://learn.microsoft.com/azure/devops/pipelines/languages/android
#trigger:
#- feature/azure-cicd
pool:
vmImage: 'macos-latest'
steps:
- bash: |
# Install AVD files
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install 'system-images;android-19;google_apis;x86'
echo "AVD system-image successfully downloaded and installed."
displayName: 'Download and install emulator image'
- bash: |
# Create emulator
echo "no" | $ANDROID_HOME/tools/bin/avdmanager create avd -n xamarin_android_emulator -k 'system-images;android-19;google_apis;x86' --force
$ANDROID_HOME/emulator/emulator -list-avds
displayName: 'Create emulator'
- bash: |
# Start emulator in background
nohup $ANDROID_HOME/emulator/emulator -avd xamarin_android_emulator -no-snapshot > /dev/null 2>&1 &
$ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
$ANDROID_HOME/platform-tools/adb devices
echo "Emulator started"
displayName: 'Start emulator'
- bash: |
./gradlew testdevelopDebug connectedMockDebugAndroidTest --stacktrace --no-daemon
./gradlew --stop
displayName: 'Run Instrumented Tests'
continueOnError: true
This works perfect when I use android-28 instead of android-19
Is there any change that I need to make in my pipeline such that I can launch the emulator?
Any help is much appreciated
The adb call in yml was done to get the status and check that locally. In the yml I was trying to pass the while loop into adb.
This example depicts the right usage and solution:
https://stackoverflow.com/a/38896494/
while [ "`adb shell getprop sys.boot_completed | tr -d '\r' `" != "1" ] ; do sleep 1; done

No tests found when enable ANDROIDX_TEST_ORCHESTRATOR(1.4.0)

I've read related question
However, I'm using the 'androidx.test:orchestrator:1.4.0', which should not has the bug below 1.2.0.
My case is, I will get error: com.android.build.gradle.internal.testing.ConnectedDevice > No tests found.[GM1910 - 11] FAILED if I enable :
testOptions {
execution 'ANDROIDX_TEST_ORCHESTRATOR'
}
I've done the prefix operations:
$ curl -O https://dl.google.com/android/maven2/androidx/test/orchestrator/1.4.0/orchestrator-1.4.0.apk
$ curl -O https://dl.google.com/android/maven2/androidx/test/services/test-services/1.4.0/test-services-1.4.0.apk
$ adb install -r orchestrator-1.4.0.apk
$ adb install -r test-services-1.4.0.apk
$ adb shell 'CLASSPATH=$(pm path androidx.test.services) app_process / \
androidx.test.services.shellexecutor.ShellMain am instrument -w -e \
targetInstrumentation com.example.notroid/androidx.test.runner.AndroidJUnitRunner \
androidx.test.orchestrator/.AndroidTestOrchestrator'
Time: 0
OK (0 tests)

How can i run my adb command through apk

My ADB command is,
adb shell am instrument -w -r -e debug false -e class com.example.deepak.myapplication.ExampleInstrumentedTest com.example.deepak.myapplication.test/android.support.test.runner.AndroidJUnitRunner

Differences between "echo $variable" and actual output of it

I'm trying to fix a bash script. The part of relevance is this one:
function do_get_apks {(
mkdir -p apks
cd apks
adb shell pm list packages > installed_packages
adb shell pm list packages -3 > installed_packages_user
while read p; do
# remove trailing 'package'
package=$(echo "${p/package:/}" | tr -d '\r\n')
mkdir "$package"
echo "$package"
echo "adb shell pm path $package"
apkpath=$(adb shell pm path "$package")
echo "$apkpath"
apkpath1=$(echo "$apkpath" | grep "package")
echo "$apkpath1"
apkpath2=$(echo "$apkpath" | grep "package" | tr -d '[[:space:]]')
echo "$apkpath2"
apkpath=$(adb shell pm path "$package" | grep package | tr -d '[[:space:]]')
adb pull ${apkpath/package:/} "$package/"
adb shell dumpsys package "$package" > "$package"/info
done < installed_packages)}
Thing is there are incongruities between the output of the command echo "adb shell pm path $package" where package is com.mobeam.barcodeService which returns a list of all the packages, and the actual content of the command "adb shell pm path com.mobeam.barcodeService", which returns just package:/system/app/BeamService/BeamService.apk (which is the desired output)
It looks like the script is returning a list of packages instead of the desired one. You can test this script with adb and any Android Device.
EDIT: Just to clarify, the error I'm getting is the following one:
adb: error: SendRequest failed: path too long: 3922
adb: error: failed to stat remote object
'com.samsung.android.provider.filterproviderpackage:com.monotype.android.font.rosemarypackage:com.sec.android.app.DataCreatepackage:com.gd.mobicore.papackage:com.sec.android.widgetapp.samsungappspackage:com.google.android.youtubepackage:com.samsung.android.app.galaxyfinderpackage:com.sec.android.app.chromecustomizationspackage:com.android.providers.telephonypackage:com.sec.android.app.parserpackage:com.google.android.googlequicksearchboxpackage:com.vlingo.midaspackage:com.android.providers.calendarpackage:com.osp.app.signinpackage:com.sec.android.directsharepackage:com.samsung.clipboardsaveservicepackage:com.sec.automationpackage:com.android.providers.mediapackage:com.google.android.onetimeinitializerpackage:com.sec.android.widgetapp.digitalclockpackage:com.android.wallpapercropperpackage:com.samsung.android.provider.shootingmodeproviderpackage:com.sec.android.app.wfdbrokerpackage:com.sec.android.app.safetyassurancepackage:com.sec.factory.camerapackage:org.simalliance.openmobileapi.servicepackage:com.sec.usbsettingspackage:com.samsung.android.easysetuppackage:com.android.documentsuipackage:com.android.externalstoragepackage:com.sec.factorypackage:com.android.htmlviewerpackage:com.whatsapppackage:com.android.mms.servicepackage:com.android.providers.downloadspackage:com.qualcomm.qti.auth.sampleauthenticatorservicepackage:com.samsung.ucs.agent.bootpackage:com.sec.android.theme.naturalpackage:com.wsomacppackage:com.sec.android.Kiespackage:com.qapp.secprotectpackage:com.sec.android.app.voicenotepackage:com.sec.android.app.easylauncherpackage:com.samsung.knox.rcp.componentspackage:com.sec.android.widgetapp.easymodecontactswidgetpackage:com.samsung.android.intelligenceservice2package:samsunges.sclubpackage:com.sec.di.SmartSelfShotpackage:com.samsung.android.MtpApplicationpackage:com.sec.android.app.factorykeystringpackage:com.sec.android.app.samsungappspackage:com.sec.android.emergencymode.servicepackage:com.google.android.configupdaterpackage:com.sec.android.app.wlantestpackage:com.sec.android.widgetapp.SPlannerAppWidgetpackage:com.sec.android.widgetapp.activeapplicationwidgetpackage:com.sec.android.app.billingpackage:com.sec.android.app.minimode.respackage:com.android.defcontainerpackage:com.sec.android.daemonapppackage:com.sec.enterprise.knox.attestationpackage:com.android.vendingpackage:com.android.pacprocessorpackage:com.dsi.ant.service.socketpackage:com.sec.android.app.popupuireceiverpackage:com.sec.android.AutoPreconfigpackage:com.sec.android.providers.securitypackage:com.sec.android.provider.badgepackage:com.android.certinstallerpackage:com.samsung.android.securitylogagentpackage:com.android.carrierconfigpackage:com.google.android.marvin.talkbackpackage:com.sec.android.app.taskmanagerpackage:com.samsung.android.app.assistantmenupackage:com.samsung.SMTpackage:com.sec.android.ofviewerpackage:com.samsung.everglades.videopackage:androidpackage:com.android.contactspackage:com.samsung.hs20providerpackage:com.samsung.android.sm.devicesecuritypackage:com.sec.android.casual2package:com.samsung.android.smartfacepackage:com.android.mmspackage:com.android.nfcpackage:com.android.stkpackage:com.sec.knox.foldercontainerpackage:com.android.backupconfirmpackage:com.sec.android.cloudagent.dropboxoobedummypackage:com.samsung.klmsagentpackage:com.samsung.android.app.memopackage:flipboard.apppackage:com.sec.android.app.SecSetupWizardpackage:com.android.statementservicepackage:com.google.android.gmpackage:com.sec.android.app.hwmoduletestpackage:com.sec.bcservicepackage:com.android.calendarpackage:com.sec.modem.settingspackage:com.android.phasebeampackage:com.monotype.android.font.samsungsanspackage:com.sec.android.app.sysscopepackage:com.google.android.instantapps.supervisorpackage:com.sec.android.app.wallpaperchooserpackage:com.sec.android.app.servicemodeapppackage:com.sec.android.preloadinstallerpackage:com.sec.android.widgpackage:/system/app/BeamService/BeamService.apk': File name too long

Running a shell script on android device using adb

Manually, we can run:
adb shell
su
chmod 666 /dev/graphics/fb0
export CLASSPATH=/data/local/device.jar
export LD_LIBRARY_PATH=/data/local
exec app_process /system/bin com.device.client.Main /data/local/device.conf &
However, we need to be able to run that from a bash script on the computer compiling the program.
I have tried:
adb shell "su
&& chmod 666 /dev/graphics/fb0
&& export CLASSPATH=/data/local/device.jar
&& export LD_LIBRARY_PATH=/data/local
&& exec app_process /system/bin com.device.client.Main /data/local/device.conf &"
But since we are entering the su shell, this does not work.
Can you please suggest a solution?
Try this:
adb shell "su -c '
chmod 666 /dev/graphics/fb0
&& export CLASSPATH=/data/local/device.jar
&& export LD_LIBRARY_PATH=/data/local
&& exec app_process /system/bin com.device.client.Main
/data/local/device.conf &'"
It might be possible to simplify it, too:
adb shell "su -c '
chmod 666 /dev/graphics/fb0 &&
CLASSPATH=/data/local/device.jar
LD_LIBRARY_PATH=/data/local
app_process /system/bin com.device.client.Main
/data/local/device.conf &'"
This is because you can set environment variables for one job just by prepending them on the line, rather than the export this, export that form.

Categories

Resources