Related
I observed that when i use Logcat with Eclipse with ADT for Android, I get messages from many other applications as well. Is there a way to filter this and show only messages from my own application only.
Linux and OS X
Use ps/grep/cut to grab the PID, then grep for logcat entries with that PID. Here's the command I use:
adb logcat | grep -F "`adb shell ps | grep com.asanayoga.asanarebel | tr -s [:space:] ' ' | cut -d' ' -f2`"
(You could improve the regex further to avoid the theoretical problem of unrelated log lines containing the same number, but it's never been an issue for me)
This also works when matching multiple processes.
Windows
On Windows you can do:
adb logcat | findstr com.example.package
Package names are guaranteed to be unique so you can use the Log function with the tag as your package name and then filter by package name:
NOTE: As of Build Tools 21.0.3 this will no longer work as TAGS are restricted to 23 characters or less.
Log.<log level>("<your package name>", "message");
adb -d logcat <your package name>:<log level> *:S
-d denotes an actual device and -e denotes an emulator. If there's more than 1 emulator running you can use -s emulator-<emulator number> (eg, -s emulator-5558)
Example: adb -d logcat com.example.example:I *:S
Or if you are using System.out.print to send messages to the log you can use adb -d logcat System.out:I *:S to show only calls to System.out.
You can find all the log levels and more info here: https://developer.android.com/studio/command-line/logcat.html
http://developer.android.com/reference/android/util/Log.html
EDIT: Looks like I jumped the gun a little and just realized you were asking about logcat in Eclipse. What I posted above is for using logcat through adb from the command line. I'm not sure if the same filters transfer over into Eclipse.
Since Android 7.0, logcat has --pid filter option, and pidof command is available, replace com.example.app to your package name.
(ubuntu terminal / Since Android 7.0)
adb logcat --pid=`adb shell pidof -s com.example.app`
or
adb logcat --pid=$(adb shell pidof -s com.example.app)
For more info about pidof command:
https://stackoverflow.com/a/15622698/7651532
Add filter
Specify names
Choose your filter.
This works for me with USB debugging:
The solution is to use your device's own logcat directly via shell.
Connect the device and use:
adb shell
Use logcat after the shell is set up:
logcat | grep com.yourapp.packagename
For me this works in mac Terminal
Got to the folder where you have adb then type below command in terminal
./adb logcat MyTAG:V AndroidRuntime:E *:S
Here it will filter all logs of MyTAG and AndroidRuntime
Update May 17
It's been a few years, and thing have changed. And Eclipse is no longer officially supported. So here's two more up-to-date approaches:
1. Android Studio
In the Android monitor toolbox, you can filter logcat per debuggable process. Normally, when you develop an application it is a debuggable process. Every once in a while I am having issues with this, and a do the following:
Tools -> Android -> Enable ADB Integration.
If it was already enabled, then toggle it off, and then back on
Unplug and replug your mobile device.
There are also options to filter via regex and the debug level
2. logcat-color
This is a nice python wrapper on top of adb logcat if you want to use a terminal based solution. The good thing about it is that you can save multiple configurations and simply reuse them. Filtering by tags is quite reliable. You can also filter by package to see logs of one or more apps only, but you start logcat-color right before launching your app.
Old Answer:
It seems that I can't comment to previous answers, so I will post a new one.
This is a comment to Tom Mulcahy's answer, that shows how the command should change so as to work on most devices, since adb shell ps PID column is variable.
NOTE: The command below works for the cases where you have connected many devices. So device id is needed. Otherwise, you can simply omit the brackets '[', ']'
1. To find out the column of pid, type:
adb [-s DEVICE_ID] shell ps | head -n 1
Now memorise the column number for the PID. Numbering starts from 1.
2. Then type the following:
adb [-s DEVICE_ID] logcat | grep $(adb [-s DEVICE_ID] shell ps \
| grep "com.example" | awk -F" " ' {print $PUT_COLUMN_HERE}')
Simply put the column you memorised in PUT_COLUMN_HERE, e.g. $5
Caveat
Each time you re-run your application, you have to re-run the 2nd command, because the application gets a new PID from the OS.
Ubuntu : adb logcat -b all -v color --pid=`adb shell pidof -s com.packagename` With color and continous log of app
This has been working for me in git bash:
$ pid=$(adb shell ps | grep <package name> | cut -c11-15) ; adb logcat | grep $pid
put this to applog.sh
#!/bin/sh
PACKAGE=$1
APPPID=`adb -d shell ps | grep "${PACKAGE}" | cut -c10-15 | sed -e 's/ //g'`
adb -d logcat -v long \
| tr -d '\r' | sed -e '/^\[.*\]/ {N; s/\n/ /}' | grep -v '^$' \
| grep " ${APPPID}:"
then:
applog.sh com.example.my.package
Using Windows command prompt: adb logcat -d | findstr <package>.
*This was first mentioned by jj_, but it took me ages to find it in the comments...
adb logcat -e "appname"
This works prefectly when filtering rows for one app only.
If you are using Android Studio you can select the process from which you want to receive logcats.
Here is the screenshot.
I wrote a shell script for filtering logcat by package name, which I think is more reliable than using
ps | grep com.example.package | cut -c10-15
It uses /proc/$pid/cmdline to find out the actual pid, then do a grep on logcat
https://gist.github.com/kevinxucs/7340e1b1dd2239a2b04a
Use -s !
You should use your own tag, look at:
http://developer.android.com/reference/android/util/Log.html
Like.
Log.d("AlexeysActivity","what you want to log");
And then when you want to read the log use>
adb logcat -s AlexeysActivity
That filters out everything that doesn't use the same tag.
Source
ADT v15 for Eclipse let you specify an application name (which is actually the package value in your androidmanifest.xml).
I love being able to filter by app, but the new logcat has a bug with the autoscroll. When you scroll up a little to look at previous logs, it automatically scrolls back to the bottom in a couple seconds. It seems scrolling 1/2 way up the log does keep it from jumping back to the bottom, but that's often useless.
EDIT: I tried specifying an app filter from the command-line -- but no luck. If someone figures this out OR how to stop the autoscroll, please let me know.
LogCat Application messages
As a variant you can use third party script PID Cat by Jake Wharton. This script has two major advantages:
shows log entries for processes from a specific application package
color logcat
From documentation:
During application development you often want to only display log messages coming from your app. Unfortunately, because the process ID changes every time you deploy to the phone it becomes a challenge to grep for the right thing.
This script solves that problem by filtering by application package.
An output looks like
In order to access the logcats you first need to install ADB command-line tool. ADB command-line tool is a part of android studio platform tools and can be downloaded from here. After this, you need to set the path/environment variable for adb tools. Now you can access logcat from eclipse terminal/ intellij terminal or mac terminal in case you are using a macbook.
adb logcat : To get entire logcat.
adb shell pidof 'com.example.debug' : To get the process id of your app.
adb logcat pid=<pid> : To get logcat specific to your app.
adb logcat pid=<pid>|grep 'sometext' : To filter logcat on basis of some text.
For more info about filtering logcats read this.
On Windows 10, using Ionic, what worked great to me was combine 'findstr' with the "INFO:CONSOLE" generated by all App messages.
So, my command in command line is:
adb logcat | findstr INFO:CONSOLE
I'm not sure there's a way to only see system messages regarding your app, but you can filter based on a string. If you're doing a log within the program, you can just include a certain unique keyword, and filter based on that word.
Try: Window -> Preferences -> Android -> LogCat. Change field "Show logcat view if ..." the value "VERBOSE". It helped me.
If you are using Eclipse, press the green + sign in the logCat window below and put your package name (com.example.yourappname) in the by Application Name box. Also, choose any name comfortable to you in Filter Name box and click ok. You will see only messages related to your application when the filter you just added is chosen from the left pane in the logCat.
Give your log a name. I called mine "wawa".
In Android Studio, go to Android-> Edit Filter Configurations
Then type in the name you gave the logs. In my case, it's called "wawa". Here are some examples of the types of filters you can do. You can filter by System.out, System.err, Logs, or package names:
This is probably the simplest solution.
On top of a solution from Tom Mulcahy, you can further simplify it like below:
alias logcat="adb logcat | grep `adb shell ps | egrep '\bcom.your.package.name\b' | cut -c10-15`"
Usage is easy as normal alias. Just type the command in your shell:
logcat
The alias setup makes it handy. And the regex makes it robust for multi-process apps, assuming you care about the main process only.
Of coz you can set more aliases for each process as you please. Or use hegazy's solution. :)
In addition, if you want to set logging levels, it is
alias logcat-w="adb logcat *:W | grep `adb shell ps | egrep '\bcom.your.package.name\b' | cut -c10-15`"
You can use below command to fetch verbose logs for your application package
adb logcat com.example.myapp:V *:S
Also if you have rolled out your app and you want to fetch error logs from released app, you can use below command.
adb logcat AndroidRuntime:E *:S
I am usually adding something in the log messages to make it distinct. Or for example unity app you can use "Unity" as matching string.
For mac :
adb logcat | grep "MyUniqueString"
for Windows (powershell ):
adb logcat | Select-String "MyUniqueString"
I have different approach, you can try access to local device's shell.
adb shell
and then follow by
logcat | grep com.package.name
This print all containing that package.
Alternatively, You can try flutter logs --verbose
Another way of getting logs of exact package name when you are inside the shell:
logcat --pid $(ps -ef | grep -E "com.example.app\$" | awk '{print $2}')
I tried to use Tom Mulcahy's answer but unfortunately it was not working for applications with multiple processes so I edit it to fit my needs.
#!/bin/bash
if [ "$#" -ne 1 ]; then echo "Illegal number of parameters"; exit 1; fi
echo "Lof for package name: $1"
PROCESSES=`adb shell ps | grep "$1" | cut -c10-15`
NUM_OF_PROCESSES=`echo "$PROCESSES" | wc -l`
if [ $NUM_OF_PROCESSES -eq 0 ]; then echo "The application is not running!"; exit 1; fi
COUNTER=1
for process in $PROCESSES; do
if [ $COUNTER -eq 1 ]; then GREP_TEXT="("; fi
GREP_TEXT+=$process
if [ $COUNTER -eq $NUM_OF_PROCESSES ]; then GREP_TEXT+=")"; else GREP_TEXT+="|"; fi
let COUNTER=COUNTER+1
if [ $COUNTER -gt $NUM_OF_PROCESSES ]; then break; fi
done
adb logcat | grep -E "$GREP_TEXT"
In addition to Tom Mulcahy's answer, if you want to filter by PID on Windows' console, you can create a little batch file like that:
#ECHO OFF
:: find the process id of our app (2nd token)
FOR /F "tokens=1-2" %%A IN ('adb shell ps ^| findstr com.example.my.package') DO SET PID=%%B
:: run logcat and filter the output by PID
adb logcat | findstr %PID%
I observed that when i use Logcat with Eclipse with ADT for Android, I get messages from many other applications as well. Is there a way to filter this and show only messages from my own application only.
Linux and OS X
Use ps/grep/cut to grab the PID, then grep for logcat entries with that PID. Here's the command I use:
adb logcat | grep -F "`adb shell ps | grep com.asanayoga.asanarebel | tr -s [:space:] ' ' | cut -d' ' -f2`"
(You could improve the regex further to avoid the theoretical problem of unrelated log lines containing the same number, but it's never been an issue for me)
This also works when matching multiple processes.
Windows
On Windows you can do:
adb logcat | findstr com.example.package
Package names are guaranteed to be unique so you can use the Log function with the tag as your package name and then filter by package name:
NOTE: As of Build Tools 21.0.3 this will no longer work as TAGS are restricted to 23 characters or less.
Log.<log level>("<your package name>", "message");
adb -d logcat <your package name>:<log level> *:S
-d denotes an actual device and -e denotes an emulator. If there's more than 1 emulator running you can use -s emulator-<emulator number> (eg, -s emulator-5558)
Example: adb -d logcat com.example.example:I *:S
Or if you are using System.out.print to send messages to the log you can use adb -d logcat System.out:I *:S to show only calls to System.out.
You can find all the log levels and more info here: https://developer.android.com/studio/command-line/logcat.html
http://developer.android.com/reference/android/util/Log.html
EDIT: Looks like I jumped the gun a little and just realized you were asking about logcat in Eclipse. What I posted above is for using logcat through adb from the command line. I'm not sure if the same filters transfer over into Eclipse.
Since Android 7.0, logcat has --pid filter option, and pidof command is available, replace com.example.app to your package name.
(ubuntu terminal / Since Android 7.0)
adb logcat --pid=`adb shell pidof -s com.example.app`
or
adb logcat --pid=$(adb shell pidof -s com.example.app)
For more info about pidof command:
https://stackoverflow.com/a/15622698/7651532
Add filter
Specify names
Choose your filter.
This works for me with USB debugging:
The solution is to use your device's own logcat directly via shell.
Connect the device and use:
adb shell
Use logcat after the shell is set up:
logcat | grep com.yourapp.packagename
For me this works in mac Terminal
Got to the folder where you have adb then type below command in terminal
./adb logcat MyTAG:V AndroidRuntime:E *:S
Here it will filter all logs of MyTAG and AndroidRuntime
Update May 17
It's been a few years, and thing have changed. And Eclipse is no longer officially supported. So here's two more up-to-date approaches:
1. Android Studio
In the Android monitor toolbox, you can filter logcat per debuggable process. Normally, when you develop an application it is a debuggable process. Every once in a while I am having issues with this, and a do the following:
Tools -> Android -> Enable ADB Integration.
If it was already enabled, then toggle it off, and then back on
Unplug and replug your mobile device.
There are also options to filter via regex and the debug level
2. logcat-color
This is a nice python wrapper on top of adb logcat if you want to use a terminal based solution. The good thing about it is that you can save multiple configurations and simply reuse them. Filtering by tags is quite reliable. You can also filter by package to see logs of one or more apps only, but you start logcat-color right before launching your app.
Old Answer:
It seems that I can't comment to previous answers, so I will post a new one.
This is a comment to Tom Mulcahy's answer, that shows how the command should change so as to work on most devices, since adb shell ps PID column is variable.
NOTE: The command below works for the cases where you have connected many devices. So device id is needed. Otherwise, you can simply omit the brackets '[', ']'
1. To find out the column of pid, type:
adb [-s DEVICE_ID] shell ps | head -n 1
Now memorise the column number for the PID. Numbering starts from 1.
2. Then type the following:
adb [-s DEVICE_ID] logcat | grep $(adb [-s DEVICE_ID] shell ps \
| grep "com.example" | awk -F" " ' {print $PUT_COLUMN_HERE}')
Simply put the column you memorised in PUT_COLUMN_HERE, e.g. $5
Caveat
Each time you re-run your application, you have to re-run the 2nd command, because the application gets a new PID from the OS.
Ubuntu : adb logcat -b all -v color --pid=`adb shell pidof -s com.packagename` With color and continous log of app
This has been working for me in git bash:
$ pid=$(adb shell ps | grep <package name> | cut -c11-15) ; adb logcat | grep $pid
put this to applog.sh
#!/bin/sh
PACKAGE=$1
APPPID=`adb -d shell ps | grep "${PACKAGE}" | cut -c10-15 | sed -e 's/ //g'`
adb -d logcat -v long \
| tr -d '\r' | sed -e '/^\[.*\]/ {N; s/\n/ /}' | grep -v '^$' \
| grep " ${APPPID}:"
then:
applog.sh com.example.my.package
Using Windows command prompt: adb logcat -d | findstr <package>.
*This was first mentioned by jj_, but it took me ages to find it in the comments...
adb logcat -e "appname"
This works prefectly when filtering rows for one app only.
If you are using Android Studio you can select the process from which you want to receive logcats.
Here is the screenshot.
I wrote a shell script for filtering logcat by package name, which I think is more reliable than using
ps | grep com.example.package | cut -c10-15
It uses /proc/$pid/cmdline to find out the actual pid, then do a grep on logcat
https://gist.github.com/kevinxucs/7340e1b1dd2239a2b04a
Use -s !
You should use your own tag, look at:
http://developer.android.com/reference/android/util/Log.html
Like.
Log.d("AlexeysActivity","what you want to log");
And then when you want to read the log use>
adb logcat -s AlexeysActivity
That filters out everything that doesn't use the same tag.
Source
ADT v15 for Eclipse let you specify an application name (which is actually the package value in your androidmanifest.xml).
I love being able to filter by app, but the new logcat has a bug with the autoscroll. When you scroll up a little to look at previous logs, it automatically scrolls back to the bottom in a couple seconds. It seems scrolling 1/2 way up the log does keep it from jumping back to the bottom, but that's often useless.
EDIT: I tried specifying an app filter from the command-line -- but no luck. If someone figures this out OR how to stop the autoscroll, please let me know.
LogCat Application messages
As a variant you can use third party script PID Cat by Jake Wharton. This script has two major advantages:
shows log entries for processes from a specific application package
color logcat
From documentation:
During application development you often want to only display log messages coming from your app. Unfortunately, because the process ID changes every time you deploy to the phone it becomes a challenge to grep for the right thing.
This script solves that problem by filtering by application package.
An output looks like
In order to access the logcats you first need to install ADB command-line tool. ADB command-line tool is a part of android studio platform tools and can be downloaded from here. After this, you need to set the path/environment variable for adb tools. Now you can access logcat from eclipse terminal/ intellij terminal or mac terminal in case you are using a macbook.
adb logcat : To get entire logcat.
adb shell pidof 'com.example.debug' : To get the process id of your app.
adb logcat pid=<pid> : To get logcat specific to your app.
adb logcat pid=<pid>|grep 'sometext' : To filter logcat on basis of some text.
For more info about filtering logcats read this.
On Windows 10, using Ionic, what worked great to me was combine 'findstr' with the "INFO:CONSOLE" generated by all App messages.
So, my command in command line is:
adb logcat | findstr INFO:CONSOLE
I'm not sure there's a way to only see system messages regarding your app, but you can filter based on a string. If you're doing a log within the program, you can just include a certain unique keyword, and filter based on that word.
Try: Window -> Preferences -> Android -> LogCat. Change field "Show logcat view if ..." the value "VERBOSE". It helped me.
If you are using Eclipse, press the green + sign in the logCat window below and put your package name (com.example.yourappname) in the by Application Name box. Also, choose any name comfortable to you in Filter Name box and click ok. You will see only messages related to your application when the filter you just added is chosen from the left pane in the logCat.
Give your log a name. I called mine "wawa".
In Android Studio, go to Android-> Edit Filter Configurations
Then type in the name you gave the logs. In my case, it's called "wawa". Here are some examples of the types of filters you can do. You can filter by System.out, System.err, Logs, or package names:
This is probably the simplest solution.
On top of a solution from Tom Mulcahy, you can further simplify it like below:
alias logcat="adb logcat | grep `adb shell ps | egrep '\bcom.your.package.name\b' | cut -c10-15`"
Usage is easy as normal alias. Just type the command in your shell:
logcat
The alias setup makes it handy. And the regex makes it robust for multi-process apps, assuming you care about the main process only.
Of coz you can set more aliases for each process as you please. Or use hegazy's solution. :)
In addition, if you want to set logging levels, it is
alias logcat-w="adb logcat *:W | grep `adb shell ps | egrep '\bcom.your.package.name\b' | cut -c10-15`"
You can use below command to fetch verbose logs for your application package
adb logcat com.example.myapp:V *:S
Also if you have rolled out your app and you want to fetch error logs from released app, you can use below command.
adb logcat AndroidRuntime:E *:S
I am usually adding something in the log messages to make it distinct. Or for example unity app you can use "Unity" as matching string.
For mac :
adb logcat | grep "MyUniqueString"
for Windows (powershell ):
adb logcat | Select-String "MyUniqueString"
I have different approach, you can try access to local device's shell.
adb shell
and then follow by
logcat | grep com.package.name
This print all containing that package.
Alternatively, You can try flutter logs --verbose
Another way of getting logs of exact package name when you are inside the shell:
logcat --pid $(ps -ef | grep -E "com.example.app\$" | awk '{print $2}')
I tried to use Tom Mulcahy's answer but unfortunately it was not working for applications with multiple processes so I edit it to fit my needs.
#!/bin/bash
if [ "$#" -ne 1 ]; then echo "Illegal number of parameters"; exit 1; fi
echo "Lof for package name: $1"
PROCESSES=`adb shell ps | grep "$1" | cut -c10-15`
NUM_OF_PROCESSES=`echo "$PROCESSES" | wc -l`
if [ $NUM_OF_PROCESSES -eq 0 ]; then echo "The application is not running!"; exit 1; fi
COUNTER=1
for process in $PROCESSES; do
if [ $COUNTER -eq 1 ]; then GREP_TEXT="("; fi
GREP_TEXT+=$process
if [ $COUNTER -eq $NUM_OF_PROCESSES ]; then GREP_TEXT+=")"; else GREP_TEXT+="|"; fi
let COUNTER=COUNTER+1
if [ $COUNTER -gt $NUM_OF_PROCESSES ]; then break; fi
done
adb logcat | grep -E "$GREP_TEXT"
In addition to Tom Mulcahy's answer, if you want to filter by PID on Windows' console, you can create a little batch file like that:
#ECHO OFF
:: find the process id of our app (2nd token)
FOR /F "tokens=1-2" %%A IN ('adb shell ps ^| findstr com.example.my.package') DO SET PID=%%B
:: run logcat and filter the output by PID
adb logcat | findstr %PID%
I have a couple of shell scripts stored in the /Scripts folder of my AppleScript application.
I can access them by setting my base path
set basePath to POSIX path of ((path to me as text)) & "Contents/Resources/Scripts/"
But I'm only able to run the script if I call the Terminal app
-- This works
tell application "Terminal"
set currentTab to do script (basePath & "install_key.sh")
end tell
-- This does not work
do shell script basePath & "install_key.sh"
The error on do shell script complains about not being able to find adb (Android Debug Bridge)
FWIW, here is the shell script in question (install_key.sh)
#!/bin/bash
#Find script directory
DIR="$( cd "$( dirname "$0" )" && pwd )"
adb push $DIR"/key-dev.txt" /sdcard/ &&
adb shell mv /sdcard/key-dev.txt /sdcard/key.txt
Problem
If I understand correctly, your main issue is that your script cannot detect and hold the presence of a specific command located on a system.
Solution
I believe the following code will be effective in helping you achieve your goal. This applescript allows you to find whether ADB is stored on a system and store it's path in a variable. You can add the variable to your path and export as others have suggested or have a look at the export process in Apple's TN2065.
If ADB is not found on a system then users can receive a prompt telling them what actions to take (if that aligns with your use-case or you could begin the install sequence for ADB). To test the behavior of the script you can simply change the adp to some other (fake) command that does not exist on your system. I've added the path to the dialog so that you can see the do shell is passing the contents of the which command into a variable.
try
set adbPath to do shell script "which adb"
on error errStr number errorNumber
-- If our own error number, warn about bad data.
if the errorNumber is not equal to 0 then
display dialog "ADB is not loaded onto system. Please load ADB and run this app again"
return 0 -- Return the default value (0).
else
-- An unknown error occurred. Resignal, so the caller
-- can handle it, or AppleScript can display the number.
error errStr number errorNumber
end if
end try
if length of adbPath > 0 then display dialog "ADB found continue processing..." & adbPath
The structure defined in the TN2065 above is essentially:
$ VAR=something; export VAR $ osascript -e 'do shell script "echo $VAR"' something
You might also want to try the administrator option when calling the shell script:
do shell script "command" user name "me" password "mypassword" with administrator privileges
The Technical Note TN2065: do shell script in AppleScript is the key reference for this kind of issues.
when you use just a command name instead of a complete path, the shell
uses a list of directories (known as your PATH) to try and find the
complete path to the command. For security and portability reasons, do
shell script ignores the configuration files that an interactive shell
would read, so you don’t get the customizations you would have in
Terminal.
First: find the full path of adb
you have to open a Terminal and issue the following command:
$ which adb
suppose the response is:
/Users/ronda/projects/android/sdk/platform-tools/adb
this means that the path of adb is:
/Users/ronda/projects/android/sdk/platform-tools
, now we have several way to address the problem, for example follow one of these two options:
Option1: Fix the AppleScript
do shell script "PATH=${PATH}:/Users/ronda/projects/android/sdk/platform-tools; export PATH; echo $PATH; " & basePath & "install_key.sh"
Option2: Fix the shell script
for example you could specify full path to the adb command in your .sh this way:
#!/bin/bash
#Find script directory
DIR="$( cd "$( dirname "$0" )" && pwd )"
/Users/ronda/projects/android/sdk/platform-tools/adb push $DIR"/key-dev.txt" /sdcard/ &&
/Users/ronda/projects/android/sdk/platform-tools/adb shell mv /sdcard/key-dev.txt /sdcard/key.txt
The simplest solution would be running the same bash configuration as your terminal application. The main difference is that Terminal uses an interactive bash and do shell script command doesn't. To run an interactive shell you can simply execute a new one with option -i (stands for interactive). When an interactive shell is opened the ~/.bashrc file is used, while non-interactive shells don't use this file.
do shell script "bash -i <<<" & quoted form of (basePath & "install_key.sh" as text)
if you don't like that you can simply execute the bashrc file or read the path variable and set it in a do shell script.
Is there a way of running adb commands on all connected devices? To uninstall an app from all connected devices with "adb uninstall com.example.android".
The commands I am interested in is mainly install and uninstall.
I was thinking about writing a bash script for this, but I feel like someone should have done it already :)
Create a bash file and name it e.g. adb+:
#!/bin/bash
adb devices | while read -r line
do
if [ ! "$line" = "" ] && [ "$(echo "$line" | awk '{print $2}')" = "device" ]
then
device=$(echo "$line" | awk '{print $1}')
echo "$device" "$#" ...
adb -s "$device" "$#"
fi
done
Usage: ./adb+ <command>
Building on #Oli's answer, this will also let the command(s) run in parallel, using xargs. Just add this to your .bashrc file:
function adball()
{
adb devices | egrep '\t(device|emulator)' | cut -f 1 | xargs -t -J% -n1 -P5 \
adb -s % "$#"
}
and apply it by opening a new shell terminal, . ~/.bashrc, or source ~/.bashrc.
If you only want to run on devices (or only on emulators), you can change the (device|emulator) grep by removing the one you don't want. This command as written above will run on all attached devices and emulators.
the -J% argument specifies that you want xargs to replace the first occurrence of % in the utility with the value from the left side of the pipe (stdin).
NOTE: this is for BSD (Darwin / Mac OS X) xargs. For GNU/Linux xargs, the option is -I%.
-t will cause xargs to print the command it is about to run immediately before running it.
-n1 means xargs should only use at most 1 argument in each invocation of the command (as opposed to some utilities which can take multiple arguments, like rm for example).
-P5 allows up to 5 parallel processes to run simultaneously. If you want instead to run the commands sequentially, simply remove the entire -P5 argument. This also allows you to have two variations of the command (adball and adbseq, for example) -- one that runs in parallel, the other sequentially.
To prove that it is parallel, you can run a shell command that includes a sleep in it, for example:
$ adball shell "getprop ro.serialno ; date ; sleep 1 ; date ; getprop ro.serialno"
You can use this to run any adb command you want (yes, even adball logcat will work! but it might look a little strange because both logs will be streaming to your console in parallel, so you won't be able to distinguish which device a given log line is coming from).
The benefit of this approach over #dtmilano's & approach is that xargs will continue to block the shell as long as at least one of the parallel processes is still running: that means you can break out of both commands by simply using ^C, just like you're used to doing. With dtmilano's approach, if you were to run adb+ logcat, then both logcat processes would be backgrounded, and so you would have to manually kill the logcat process yourself using ps and kill or pkill. Using xargs makes it look and feel just like a regular blocking command line, and if you only have one device, then it will work exactly like adb.
This is an improved version of the script from 強大な. The original version was not matching some devices.
DEVICES=`adb devices | grep -v devices | grep device | cut -f 1`
for device in $DEVICES; do
echo "$device $# ..."
adb -s $device $#
done
To add in the ~/.bashrc or ~/.zshrc:
alias adb-all="adb devices | awk 'NR>1{print \$1}' | parallel -rkj0 --tagstring 'on {}: ' adb -s {}"
Examples:
$ adb-all shell date
$ adb-all shell getprop net.hostname
$ adb-all sideload /path/to/rom.zip
$ adb-all install /path/filename.apk
$ adb-all push /usr/local/bin/frida-server-arm64 /data/local/tmp/frida-server
Explanation: awk extracts the device id/host (first column: print $1) of every lines except the first one (NR>1) to remove the "List of devices attached" header line), then gnu parallel runs adb -s <HOSTNAME> <whatever-is-passed-to-the-alias> on whatever non-empty line (-r) in the order specified (-k, to avoid random order / fastest response order) and prepend each line with on <DEVICE>:\t for clarity, all in parallel (-j0, possible to set another number to define how many adb should be ran in parallel instead of unlimited).
:)
This is the highest result on Google, so for all Windows users coming here let me add this solution by User zingh (slightly modified to accept arbitrary commands, rather than "only" install
Batch file (adball.bat):
FOR /F "skip=1" %%x IN ('adb devices') DO start adb -s %%x %*
Call as:
adball uninstall com.mypackage
(%* takes all input parameters, my line above makes it so that all commands are passed to adb as they are, so that you can type multiple words, flags etc.)
Note: you can even use this directly from the Android Studio "run all" popup, if you install the Powershell-plugin. You can add adball to your path, then double-tap ctrl and run
powershell adball uninstall com.mypackage
adb wrapper supports selecting multiple targets for adb commands and parallel execution.
From its README:
# Installation
./install.sh ~/apps/android-sdk-linux
# Execute adb commands on all connected devices.
adb set-target all
# Execute adb commands on given devices.
adb set-target emulator-5554 C59KGT14263422
# Use GNU parallel for parallel install.
adb set-parallel true
(Disclaimer: I have written half of it)
I have file on SD-CARD and my app using it as log file.
Is it possible through the adb to watch file with all changes in real time?
Like with tail -f /sdcard/myfile.log command.
This seems to work great for me:
adb shell "while true; do cat; sleep 1; done < /sdcard/myfile.log"
You can install busybox and then:
adb shell
tail -f /path/of/your/file
But remember that you should have root access to install busybox. If you are using the emulator check this one:
How to get root access on Android emulator?
You can do this with logcat. You can add a view that will only show log entries from your app and it will be continuously updated.
There is a great app for this: Terminal IDE. It contains many linux commands, and it does not need root access. You can install it from GooglePlay. Is is free of charge (and open source, GPLv2).
One of its best features is that it can be used through telnet. Start it on your phone, and type telnetd command. It will start a telnet daemon, which listens on port 8080 by default.
After that you can connect it from your PC, with the following command: (use cygwin on windows)
telnet 192.168.1.8 8080
You should use your phone's IP address instead of the above one. After a successful connection you will have an arbitrary sized terminal on your PC, which is capable to run tail -f command on your phone. And many others, such as bash and all of its builtin commands.
Building upon Jesse's answer, to do similar with a file within an app's private storage area:
adb shell "while true; do run-as com.yourdomain.yourapp cat /data/data/com.yourdomain.yourapp/app_flutter/yourfile.txt; sleep 5; done" | egrep -o 'sometext.{0,50}'
(This example is for a flutter app on Android, but is similar minus the app_flutter directory.)
do run-as changes the user under which the command is run to the application. By default adb shell user shouldn't have access to any files under an application's private storage area.
| egrep -o 'sometext.{0,50}' the cat command sends the file contents to STDOUT. egrep is taking the contents & searching for -o (only) sometext + 50 characters" using regex (hence egrep instead of grep).
Last Line Only
Replace cat with tail -n 1.
Add --line-buffered to egrep
adb shell "while true; do run-as com.yourdomain.yourapp tail -n 1 /data/data/com.yourdomain.yourapp/app_flutter/yourfile.txt; sleep 5; done" | egrep --line-buffered -o 'sometext.{0,50}'