Android停止/暂停执行我的背景脚本? -- shell 领域 和 ssh 领域 和 scripts 领域 和 bash 领域 android 相关 的问题

Android stops/pauses execution of my background script?


简体版||繁體版
2
vote

问题

中文

简短版本:

为什么我的bash脚本(在后台运行,通过sshd启动)不在每〜30秒时运行它?(注意:sshd和脚本运行为 root < /强>!)


我有一个脚本,即我开始使用 nohup bash script.sh & ,以便它在后台运行。

脚本应该检查特定应用是否使用 netstat 以及它使用 am start task default: [ :unit_test_and_install, :espresso_test ] task :unit_test_and_install do sh './gradlew --console=verbose test installDebug installDebugAndroidTest' end task :espresso_test do devices = `adb devices` serial_numbers = devices.split(" ")[1..-1].map{|q| q.split(" ")[0] } threads = serial_numbers.map do |sn| Thread.new do sh "adb -s #{sn} shell am instrument -w -r -e package com.mycorp.myapp -e disableAnalytics true " + "com.mycorp.myapp.test/androidx.test.runner.AndroidJUnitRunner | tee tests_#{sn}.txt" end end threads.each &:join serial_numbers.each do |sn| grop = `grep "^OK .*tests" tests_#{sn}.txt` if grop == '' sh "cat tests_#{sn}.txt" abort 'FAILURES on ' + sn end end end 0 。 (这结果是不相关的)。

我已经注意到,即使脚本应该每30秒检查一次(当然大致),有时需要几分钟才能检查。我真的无法弄清楚为什么,它似乎完全随意(请注意,大多数时候手机的屏幕都在关闭的时候,一切都在后台运行。),所以我制作了一个测试标记,这是问题应该专注于简单的问题:

  task default: [ :unit_test_and_install, :espresso_test ]  task :unit_test_and_install do     sh './gradlew --console=verbose test installDebug installDebugAndroidTest' end  task :espresso_test do     devices = `adb devices`     serial_numbers = devices.split(" ")[1..-1].map{|q| q.split(" ")[0] }      threads = serial_numbers.map do |sn|         Thread.new do             sh "adb -s #{sn} shell am instrument -w -r -e package com.mycorp.myapp -e disableAnalytics true " +                     "com.mycorp.myapp.test/androidx.test.runner.AndroidJUnitRunner | tee tests_#{sn}.txt"         end     end      threads.each &:join      serial_numbers.each do |sn|         grop = `grep "^OK .*tests" tests_#{sn}.txt`          if grop == ''             sh "cat tests_#{sn}.txt"             abort 'FAILURES on ' + sn         end     end  end 1  

就是这样。使用SSHD通过 task default: [ :unit_test_and_install, :espresso_test ] task :unit_test_and_install do sh './gradlew --console=verbose test installDebug installDebugAndroidTest' end task :espresso_test do devices = `adb devices` serial_numbers = devices.split(" ")[1..-1].map{|q| q.split(" ")[0] } threads = serial_numbers.map do |sn| Thread.new do sh "adb -s #{sn} shell am instrument -w -r -e package com.mycorp.myapp -e disableAnalytics true " + "com.mycorp.myapp.test/androidx.test.runner.AndroidJUnitRunner | tee tests_#{sn}.txt" end end threads.each &:join serial_numbers.each do |sn| grop = `grep "^OK .*tests" tests_#{sn}.txt` if grop == '' sh "cat tests_#{sn}.txt" abort 'FAILURES on ' + sn end end end 2 启动。脚本只做了除了打印当前的日期时间,并且归功于nohup将它写入文件。我离开了这个运行了一段时间,然后写了另一个脚本来检查结果并在上面的30以上时打印秒数。结果:

  task default: [ :unit_test_and_install, :espresso_test ]  task :unit_test_and_install do     sh './gradlew --console=verbose test installDebug installDebugAndroidTest' end  task :espresso_test do     devices = `adb devices`     serial_numbers = devices.split(" ")[1..-1].map{|q| q.split(" ")[0] }      threads = serial_numbers.map do |sn|         Thread.new do             sh "adb -s #{sn} shell am instrument -w -r -e package com.mycorp.myapp -e disableAnalytics true " +                     "com.mycorp.myapp.test/androidx.test.runner.AndroidJUnitRunner | tee tests_#{sn}.txt"         end     end      threads.each &:join      serial_numbers.each do |sn|         grop = `grep "^OK .*tests" tests_#{sn}.txt`          if grop == ''             sh "cat tests_#{sn}.txt"             abort 'FAILURES on ' + sn         end     end  end 3  

这是从一个脚本的输出只运行4:20小时,所以执行的很多时间必须延迟,睡眠时间超过30秒,或者任何发生的东西....

有人可以解释这个吗?这是一个解决方案吗?

我怀疑这可能会与内存或电源管理有关暂停脚本,但真的不应该发生,我希望我的脚本在后台运行并睡眠30秒,而不是暂停或延迟睡眠。在这个testrun中,最高的是467秒,但到目前为止,我见过的主要脚本的最高速度超过 20分钟。这很少见,但每天发生5-10分钟的延迟发生了几次。

english

Short version:

Why is my bash script (running in the background, started via SSHD) not running every ~30 seconds when it should? (NOTE: SSHD and the script are running as root!)


I have a script that I start using nohup bash script.sh & so that it runs in the background.

The script is supposed to check whether a specific app is connected using netstat and if not it automatically reconnects using am start and input keyevent. (This turns out to be irrelevant though).

I've noticed that even though the script should check every 30 seconds (roughly of course), sometimes it takes minutes to check. I couldn't really figure out why and it seemed completely random (note that the phone's screen is off most of the time and everything is running in the background.), so I made a testscript which is what the question should focus on for simplicity:

#!/bin/sh while : ; do     echo "$(date +'%Y-%m-%d %H:%M:%S')"     sleep 30 done 

That's it. Started via nohup bash script.sh & using SSHD. The script does nothing but print the current datetime and thanks to nohup writes it to a file. I left this running for a while and then wrote another script to check on the results and print the amount of seconds whenever it's above 30. Result:

134 127 115 127 88 113 116 99 110 116 54 44 70 75 62 82 94 68 429 62 81 126 144 39 467 71 62 

This is from the output of a script that ran for only 4:20 hours, so quite a lot of times where execution must have been delayed, the sleep was longer than 30 seconds, or whatever is going on....

Can someone explain this? And is there a solution to this?

I suspect this might have something to do with memory or power management pausing the script but really it shouldn't happen and I would like my script to run in the background and to sleep for exactly 30 seconds and not be paused or delayed. In this testrun, the highest was 467 seconds, but the highest I've seen with the main script so far was a little over 20 minutes. This is rare, but 5-10 minutes of a delay happens a few times a day.

           

回答列表

5
 
vote
vote
最佳答案
 

android关闭一些CPU和/或不要让应用程序在<一个href ="https://source.android.com/devices/tech/power/platform_mgmt#doze" rel ="noreferrer时使用它们"> dozing 。它通过Linux kernel的 Control组。其中一个 cgroups cpuset ,它控制哪个CPU被分配给哪个进程。 Android创建多个后代 cgroups cpuset 方面。 background -D0 -D1 -D2 等。

应用程序通常在 -D3 类别中,这可以使用最少号。 CPU - 通常是一两个。核心本机服务如 -D4 -D5 (以及 -D6,电话服务和运行前台服务(例如通知)或豁免的应用程序从电池优化或具有 -D7 等特权的优化,即使在设备处于睡眠模式下也可以使用CPU的 -D8 组。

所以你需要将脚本添加到 -D9 a local "dynamic" application-level port forwarding0 ,以便保持它。在脚本中:

  a local "dynamic" application-level port forwarding1  

更具侵略性,您可以握住唤醒锁定,以便设备不暂停:

  a local "dynamic" application-level port forwarding2  

在停止脚本后,不要忘记释放它( a local "dynamic" application-level port forwarding3 )。

请注意,这两种措施都可能对您的电池性能产生不利影响,特别是后者。 Android的警告:

创建和保持唤醒锁可以对主机设备的电池寿命产生巨大影响

 

Android turns off some of CPUs and/or don't let apps use them when it's dozing. It's achieved through Linux kernel's Control Groups. One of the cgroups is cpuset that controls which CPU is assigned to which processes. Android creates multiple descendant cgroups in cpuset e.g. background, foreground, system-background, top-apps etc.

Apps are normally in background category which can use least no. of CPUs - usually one or two. Core native services like vold, zygote (and system_server), telephony services, and apps which run a foreground service (e.g. notification) or those exempted from Battery Optimization or those having privileges like allow-in-power-save are put in foreground group which can use CPUs even when device is in sleep mode.

So you need to add the script to foreground cgroup in order to keep it alive. From within script:

~# echo -n $$ >/dev/cpuset/foreground/tasks 

Going even more aggressive, you can hold a wake lock so that device doesn't suspend:

~# echo -n my_script >/sys/power/wake_lock 

Don't forget to release it (echo -n my_script >/sys/power/wake_unlock) after stopping the script.

Please note that both of these measures can adversely affect your battery performance, particularly the latter. Android's warning:

Creating and holding wake locks can have a dramatic impact on the host device's battery life

 
 
         
         

相关问题

4  是否可以通过Bash启动FTP会话?  ( Is it possible to start an ftp session via bash ) 
是否可以通过BASH Shell与Android Samsung Galaxy Smartphone开始会话以远程访问文件? ...

1  如何在Cyanogenmod中修改Bash Shell提示符?  ( How to modify bash shell prompt in cyanogenmod ) 
有没有任何成功修改壳体在cyanogenmod?目前,#是非常无用的,至少显示工作目录会很好。此外,是否可以完成Tab-Taskion? ...

0  从文件名更改文件(图片,视频)时间戳  ( Change file pictures videos timestamp from filename ) 
当周围移动不同的文件和跨pc /智能手机时,最后修改日期的时间戳通常会重置为移动/复制操作的非常日期。这导致文件在某些​​应用程序(画廊)中是非按时间顺序排序的,特别是尤其适用于图像和视频。 通常,这些文件遵循img_yyyyyymmmd_hhmmss.jpg的命名约定,用于图像和vid_yyyyymmdd_hhmm...

1  平板电脑的Bash终端  ( Bash terminal on tablets ) 
我想购买一款平板电脑并使用它作为上网本,使用键盘码头工作(我仍然喜欢购买上网本的触摸屏和触摸箱选项)。我主要在Linux机器上工作,我需要SSH,VPN和远程打开X Windows的能力。是否有能够做到这一点的Android平板电脑的终端?任何关于ubuntu在平板电脑上的人? ...

0  AddOn.d Bash脚本用于在夜间刷新Android 5.1 cm12.1之后删除apks .1不起作用  ( Addon d bash script for removing apks after nightly reflash on android 5 1 cm12 ) 
我正在尝试在/system/addon.d/中使用bash脚本,从夜间Android 5.1(cm12.1)安装中,删除不需要的apks。每一个新的夜间reshash都会重新安装某些系统应用程序,以便为什么我想要脚本来反转此操作,因此我不必手动进行。 有一些备份脚本运行罚款(su,gapps),但我自己的脚本不起作用...

5  Bash - 如何检查计算机是否存在于没有IP的网络上的计算机(即仅通过设备名称)?  ( Bash how can i check if a computer exists on my network without ip i e by de ) 
如果我的手机与我的笔记本电脑相同的WiFi网络,我希望通过Tasker执行某些Shell脚本。我的初始想法是编辑 /etc/hosts 文件,但这将无法起作用,因为设备只在一个wifi网络上仅受到一个wifi网络。 更昂贵的想法是只需从手机中对网络上的每一个可能的地址都是ping,然后尝试通过ssh发送命令(例如, ...

24  是否可以从命令行激活“USB系列”Android设置?  ( Is it possible to activate the usb tethering android setting from the command ) 
我想在Bash脚本中激活"USB系列" ,因此有可能使用 adb shell 来运行命令行以更改一些Android设置? edit1 : 以下命令打开所需的设置,但不单独更改任何内容: am start -n com.android.settings/.TetherSettings 我发现的 tethe...

8  从终端仿真器运行应用程序[已关闭]  ( Running applications from a terminal emulator ) 
关闭。这个问题是 off-topic 。它目前不接受答案。 想要改进这个问题?更新这个问题,所以它是关于android爱好者堆栈交换的主题。 关闭 ...

1  在Android平板电脑上的Bash-shell(变压器垫TF701T)  ( Bash shell on android tablet transformer pad tf701t ) 
是否有任何方法可以将Android与终端仿真器一起获得完全工作的Bash Shell,该终端仿真器支持硬件键盘(德国布局)? 我至少需要的功能(终端应用程序,不是图形!): Bash使用正常的.bashrc和脚本(函数定义,别名...) ssh-client with hostname查找和执行一些scp su...

11  如何将bash设置为默认shell?  ( How to set bash as default shell ) 
当我adb与cyanogenmod中的设备时,我用漂亮的bash shell,颜色提示和bashrc呈现。我没有从/ system / xbin / bash到/ system / bin / sh的符号链接。它们如何将默认shell设置为bash而不是sh?我看过rc文件,但没有找到任何东西。我想在我的Androi...




© 2022 it.wenda123.org All Rights Reserved. 问答之家 版权所有