adb emu kill - wait for emulator to be fully killed - scripting

I am trying to write a shell script that will an android emulator and reinstall an app (in preparation for an appium test). This is my script:
#!/bin/sh
adb "kill-server"
adb emu kill
sleep 5
adb "start-server"
emulator "#api-29" &
adb "wait-for-device"
adb install -r com.mycompany.myapp.apk
The problem is that after executing adb emu kill, the terminal receives an OK message, which causes the execution to continue. But, the emulator actually takes a few seconds longer to close. If I add a 5 second sleep, then everything works fine. But, I want to wait dynamically in the event of the emulator taking longer than 5 seconds to close.
I am EXTREMELY new to shell scripting, so I appreciate your patience. Thanks!

Try monitoring adb devices for the device list to become empty, after your adb emu kill.
An emulator goes through an "offline" state before disappearing from the list. During that period the emulator is still running, and will mess up other emulator #api-29 calls.
Don't know how it's written in shell, but the sequence is:
Get adb devices serial numbers
Run Adb -s [serial number] emu kill
Iterate till no serial numbers are found

Try this:
#!/bin/sh
start adb "kill-server"
start adb emu kill
sleep 5
start adb "start-server"
start cmed.exe /k emulator "#api-29"
start adb "wait-for-device"
start adb install -r com.mycompany.myapp.apk

Related

how to stop appium server through command line?

The command I'm using to start the Appium server:
node appium --address 127.0.0.1 --port 4723 --session-override --no-reset --platform-name Android --platform-version 23 --automation-name Appium
How would I stop the server through command line?
Ctrl+c
or
Run pkill -9 -f appium in the Terminal.
If you're looking to do this programmatically, see http://discuss.appium.io/t/launching-and-stopping-appium-server-programmtically/700.
If you have a lot of instances of appium running and don't want to stop them one at a time then try the following command it will close all of htem at once:
/usr/bin/killall -KILL node
run ps -A | grep appium to see how many processes are there and if there are too many then the command aobve comes to had.

React native ERROR Packager can't listen on port 8081

When I run command react-native start, it shows Packager can't listen on port 8081.
I know the issue is about software using my port 8081 .
I use Resource Monitor to see the port, but I can't find 8081, there is no 8081
Can someone show me how to find it?
On a mac, run the following command to find id of the process which is using port 8081
sudo lsof -i :8081
Then run the following to terminate process:
kill -9 23583
Here is how it will look like
You can run the packager on another port.
$ react-native start --port=8088
Alternatively, find out what is using which ports on Windows with netstat.
$ netstat -a -b -o
Netstat gives you a PID, which you can use to kill the process.
$ taskkill /pid 1234
This error is coming because some process is already running on 8081 port. Stop that process and then run your command, it will run your code. For this first list all the process which are using this port by typing
lsof -i :8081
This command will list the process id (PID) of the process and then kill the node process by using
kill -9 <PID>
Here PID is the process id of the node process.
That picture indeed shows that your 8081 is not in use. If suggestions above haven't helped, and your mobile device is connected to your computer via usb (and you have Android 5.0 (Lollipop) or above) you could try:
$ adb reconnect
This is not necessary in most cases, but just in case, let's reset your connection with your mobile and restart adb server. Finally:
$ adb reverse tcp:8081 tcp:8081
So, whenever your mobile device tries to access any port 8081 on itself it will be routed to the 8081 port on your PC.
Or, one could try
$ killall node
Ubuntu/Unix && MacOS
My Metro Bundler was stuck and there were lots of node processes running but I didn't have any other development going on besides react-native, so I ran:
$ killall -9 node
The Metro Bundler is running through node on port 8081 by default, and it can encounter issues sometimes whereby it gets stuck (usually due to pressing CTRL+S in rapid succession with hot reloading on). If you press CTRL+C to kill the react-native run-android process, you will suddenly have a bad time because react-native-run-android will get stuck on :
Scanning folders for symlinks in /home/poop/dev/some-app/node_modules (41ms)
Fix:
$ killall -9 node
$ react-native run-android
Note: if you are developing other apps at the time, killing all the node proceses may interrupt them or any node-based services you have running, so be mindful of the sweeping nature of killall -9. If you aren't running a node-based database or app or you don't mind manually restarting them, then you should be good to go.
The reason I leave this detailed answer on this semi-unrelated question is that mine is a solution to a common semi-related problem that sadly requires 2 steps to fix but luckily only takes 2 steps get back to work.
If you want to surgically remove exactly the Metro Bundler garbage on port 8081, do the steps in the answer from RC_02, which are:
$ sudo lsof -i :8081
$ kill -9 23583
(where 23583 is the process ID)
You should kill all the processes running on port 8081 by kill -9 $(lsof -i:8081)
Take the terminal and type
fuser 8081/tcp
You will get a Process id which is using port 8081
Now kill the process
kill <pid>
Check if there is already a Node server running on your machine and then close it.
Try to run in another port like 3131. Run the command:
react-native run-android --port=3131
This might be because of McAfee using that port.
Doing simple lsof -i 8081 may not show the application and you may have to sudo it.
Do sudo lsof -i 8081 and if this command gives an output you can kill it by using
sudo launchctl remove com.mcafee.agent.macmn. After this start packager again.
There is a chance for running programs on port 8081. If you install McAfee antivirus then it's agent will be running on port 8081. So, We can't use the same for other programs.
First we have to verify that the port 8081 is listening or not.
In Windows,
Open CMD and run the command to check whether any program running on the port 8081.
netstat -ano | findstr 8081
Assume that if you got output something like this,
TCP 0.0.0.0:8081 0.0.0.0:0 LISTENING 5800
Then kill the program with ID 5800 using the following command,
taskkill /pid 5800
In Linux / Mac,
Open terminal and run the command to check whether any program running on the port 8081.
sudo lsof -i :8081
Assume that if you got output something like this,
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 59 root 18u IPv4 609033 0t0 TCP localhost:8081 (LISTEN)
Then kill the program with ID 609033 using the following command,
sudo kill -9 59
Alternatively,
You can also run the packager on another port.
react-native start --port=8088
react-native run-android --port=8088
in my case, internet on emulator is down as there is no wifi signal on emulator. Resetting emulator has worked.
In order to fix this issue, the process I have mentioned below.
Please cancel the current process of“react-native run-android” by CTRL + C or CMD + C
Close metro bundler(terminal) window command line which opened automatically.
Run the command again on terminal, “react-native run-android
First of all, in your device go to Dev. Option -> ADB over Network
after do it:
$ adb connect <your device adb network>
$ react-native run-android
(or run-ios, by the way)
if this has successfully your device has installed app-debug.apk,
open app-debug and go to Dev. Settings -> Debug server host & port for device,
type in your machine's IP address (generally, System preference -> Network), as in the example below < your machine's IP address >:8081 (whihout inequality)
finally, execute the command below
$ react-native start --port=8081
try another ports, and verify that you machine and your device are same network.
For Windows
Open PowerShell and Run as Administrator:
net stop winnat
The Windows NAT Driver service was stopped successfully.
net start winnat
The Windows NAT Driver service was started successfully.
EVD Image
I solved this issue by cleaning my Gradle cache.
Using this command:
cd android
./gradlew clean

How to use screen to issue a command in the background over an ssh session

I am used to using linux terminals and nohup over ssh to issue commands that run in the background even when logged out of the ssh session. For some reason nohup seems to be broken in the latest MACOS. For that reason I am trying to executing this small sample script using screen command.
sleep 10
echo "this is my test file" > testfile
This file is saved as tst script. And then I issue the following command.
ssh sohaib#localhost screen -dm sh testscript
However nothing happens. screen just exits quietly without writing to the file testfile.
If I run this without ssh it works as desired. What am I doing wrong here?
The issue is that after your script exits the screen exits. The -dm is for deamons, i.e., scripts that keep running.
Showing the screen exiting after 10 seconds:
On remote host (file is executable):
ttucker#merlin:~$ cat test.sh
#!/bin/bash
echo derp > /tmp/test.txt
sleep 10
Command on local machine:
[ttucker#localhost ~]$ ssh ttucker#merlin 'screen -dmS my_screen ~/test.sh'
After run.
On remote machine, a few seconds after screen is running:
ttucker#merlin:~$ screen -ls
There is a screen on:
23141.my_screen (11/21/2016 07:05:11 PM) (Detached)
1 Socket in /var/run/screen/S-ttucker.
On remote machine, over 10 seconds later:
ttucker#merlin:~$ screen -ls
No Sockets found in /var/run/screen/S-ttucker.
Modifying the script to keep running, and so, keeping the screen up:
If you are really running a script that needs to stay up you can do the following in the script:
#!/bin/bash
while true; do
# Do something
sleep 10
done
This will do something, wait 10 seconds, then loop again.
Or, detaching the screen manually:
You can ssh to the remote machine, run screen, then press Ctrl+A,D, press Ctrl and hold, then hit A then hit D. You can now exit the SSH session and the screen will stay running.

Cannot run adb shell "date `date +%m%d%H%M%Y.%S`"

I have a warning when running React Native on an Android device:
Debugger and device times had drifted by more than 60s. Please
correct this by running adb shell "date `date +%m%d%H%M%Y.%S`" on your
debugger machine
But when I run the command as suggested above, I get and operation not permitted error:
date: cannot set date: Operation not permitted
I already tried with sudo, still got same result:
sudo adb shell "date `date +%m%d%H%M%Y.%S`"
Inside the emulator goto Settings > Date & Time
Deselect Automatic timezone.
Adjust your timezone manually.
Deselect automatic date & time and set correct time
Deselecting automatic time and time zone did not work for me. Instead, I did adb shell su root date $(date +%m%d%H%M%Y.%S).
Adding "su root" is the solution to the "Operation not permitted" error.
Note that this is not equivalent to executing adb shell first and then su root date $(date +%m%d%H%M%Y.%S) (in this case $(date +%m%d%H%M%Y.%S) returns the emulator time, which is not correct, so even though the command succeeds, it does not fix the problem).
I had this problem in real android device, I had a time difference between the pc and the mobile higher than 60 second.
I solve the issue just by putting them on same time
If your phone can run adb as root you can use the following commands:
>>> adb root
restarting adbd as root
>>> adb shell "date `date +%m%d%H%M%Y.%S`"
Mon Aug 26 21:04:24 +0430 201
I had this problem and solved it by enabling 'set time automatically' in windows 10 Time and Language settings. also I enabled automatic date & time in my android phone.
The shell command seems not to work anymore. My solution is just re-starting the emulator. After restart, The date-time will be synced again. I think that the problem is because the emulator is booted from a snapshot. This kind of boot doesn't cause the time calculation incorrect.
I saw this problem last week, in my case i tried:
adb root
adb shell "date `date +%m%d%H%M%Y.%S`"
Then it's worked. Remember open the ADV first.

How to Close Xvfb after usage

I am running some tests in headless firefox using Xvfb. However, after my tests are finished I want to move back to normal display. But I am not able to do that .Here is What I am doing .
Open A Terminal
sudo Xvfb :10 -ac &
export DISPLAY=:10
Execute My Tests using RobotFramework+ Selenium
After step 4, I want to open the firefox in the same terminal but I am not able to see it as it is directed towards :10 display.
I wonder how can I shut this (xvfb :10) down so that I can open firefox and view it.
the & on the end of your 2nd command tells Linux to run it command in background. You can see the list of background commands running with $ jobs. Sample on Ubuntu16.04:
$ sudo Xvfb :10 -ac &
[1] 31294
$ jobs -l
[1]+ 31294 Running sudo Xvfb :10 -ac &
As you can see on the output above, jobs -l shows the background job and the second column of the output is the PID that can be used to kill it as $ sudo kill 31294.
Another option that may be "cleaner" is to start Xvfb just to run the command you want and quit automatic instead of keep it running in background. This way you would replace your lines 2,3 and 4 by:
xvfb-run python my_selenium_tests.py
Just replace python my_selenium_tests.py with whatever way to run your tests. It will open Xvfb just to it and close at the end.
The simple solution is to keep the old value of DISPLAY, change it to point to the xvfb, and then after the test is run you can change it back to the saved value.
This leaves the xvfb running, so you should also get the pid of that process and kill it. Otherwise, if you run this set of steps a dozen times, you'll have a dozen xvfb processes running in the background.