เรียกใช้คำสั่งเมื่อระบบไม่ได้ใช้งานและเมื่อใช้งานอีกครั้ง


15

ฉันต้องการเรียกใช้คำสั่งเมื่อผู้ใช้ไม่ได้ใช้งาน (ระบบไม่ได้ใช้งาน) ตัวอย่างเช่น:

echo "You started to be inactive."

นอกจากนี้เมื่อผู้ใช้กลับมาใช้งานอีกครั้ง (ระบบจะไม่ได้ใช้งานอีกต่อไป):

echo "You started to be active, again."

ฉันต้องการเชลล์สคริปต์ที่จะทำสิ่งนี้ สิ่งนี้เป็นไปได้หรือไม่ อาจจะมีเหตุการณ์ระบบบางอย่าง?


2
คุณสามารถเข้าไปดูรายละเอียดที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับสิ่งที่คุณต้องการบรรลุได้จริงหรือไม่?
นิลส์

3
คุณวัดความเกียจคร้านอย่างไร ผู้ใช้ที่ดูภาพยนตร์ไม่ทำงาน (เพราะเขาไม่ได้มีปฏิสัมพันธ์กับคอมพิวเตอร์) หรือไม่ เป็นผู้ใช้ที่เข้าสู่ระบบจากระยะไกลหรือไม่?
Gilles 'หยุดความชั่วร้าย'

จากสิ่งที่ฉันรู้ว่าระบบได้ในตัวนี้แนวความคิด: ไม่ได้ใช้งาน , การใช้งานและอื่น ๆ เป็นสิทธินี้หรือไม่?
IonicăBizău

@ IonicăBizău: ไม่จริง ไม่ได้ใช้งานในบริบทของระบบจะหมายถึงว่ากระบวนการทั้งหมดกำลังนอนหลับนั่นคือ 'กำลังรออะไรบางอย่าง' แม้ว่าสิ่งนี้อาจเกิดขึ้นบ่อยครั้งในระบบที่ทันสมัยและอาจเป็นกรณีส่วนใหญ่ แต่ก็ไม่ได้อยู่อย่างนั้นตราบใดที่มีบางสิ่งที่ต้องทำเสมอและหากมีการอัพเดทนาฬิกา ความเกียจคร้านโดยเฉพาะอย่างยิ่งในบริบทของคำถามของคุณเป็นหน้าที่ของผู้ใช้มากกว่าระบบและยิ่งกว่านั้นมันมักจะเชื่อมโยงกับเซสชันที่เฉพาะเจาะจง
Adaephon

@Adaephon ตกลง ในแนวคิดของฉันระบบจะไม่ทำงานเมื่อผู้ใช้ไม่ทำอะไร (เลื่อนเมาส์คลิกกดปุ่ม) ที่คอมพิวเตอร์เป็นเวลาxนาที ระบบจะใช้งานได้เมื่อผู้ใช้ทำการดำเนินการครั้งแรก: คลิกที่ปุ่มเมาส์ย้ายมันกดปุ่มและอื่น ๆ เป็นไปได้หรือไม่ที่จะตรวจพบสถานะactive * / * ที่ไม่ทำงานเหล่านี้โดยใช้เชลล์สคริปต์?
IonicăBizău

คำตอบ:


17

กระทู้ในฟอรัม ArchLinuxนี้มีโปรแกรม C สั้น ๆ ที่สอบถาม xscreensaver สำหรับข้อมูลว่าผู้ใช้ไม่ได้ใช้งานนานแค่ไหนดูเหมือนว่าจะค่อนข้างใกล้เคียงกับความต้องการของคุณ:

#include <X11/extensions/scrnsaver.h>
#include <stdio.h>

int main(void) {
    Display *dpy = XOpenDisplay(NULL);

    if (!dpy) {
        return(1);
    }

    XScreenSaverInfo *info = XScreenSaverAllocInfo();
    XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), info);
    printf("%u\n", info->idle);

      return(0);
}

บันทึกเป็นgetIdle.cและรวบรวมด้วย

gcc -o getIdle getIdle.c -lXss -lX11

เพื่อรับไฟล์ที่ปฏิบัติการgetIdleได้ โปรแกรมนี้พิมพ์ "เวลาว่าง" (ผู้ใช้ไม่ขยับ / คลิกด้วยเมาส์ไม่ใช้แป้นพิมพ์) ในหน่วยมิลลิวินาทีดังนั้นสคริปต์ทุบตีที่สร้างขึ้นจากสิ่งนี้อาจมีลักษณะเช่นนี้:

#!/bin/bash

idle=false
idleAfter=3000     # consider idle after 3000 ms

while true; do
  idleTimeMillis=$(./getIdle)
  echo $idleTimeMillis  # just for debug purposes.
  if [[ $idle = false && $idleTimeMillis -gt $idleAfter ]] ; then
    echo "start idle"   # or whatever command(s) you want to run...
    idle=true
  fi

  if [[ $idle = true && $idleTimeMillis -lt $idleAfter ]] ; then
    echo "end idle"     # same here.
    idle=false
  fi
  sleep 1      # polling interval

done

วิธีนี้ยังคงต้องการการสำรวจปกติ แต่ทำทุกสิ่งที่คุณต้องการ ...


ทำงานได้ตามที่ควร! +1
IonicăBizău

คุณมีคะแนนมากขึ้น!
IonicăBizău

2
คุณสามารถช่วยตัวเองรวบรวมโปรแกรมของคุณเองและเพียงแค่ใช้xprintidleซึ่งมีอยู่ในการกระจายส่วนใหญ่และทำสิ่งเดียวกัน
Riot

3

TMOUT in bash จะยุติเซสชันแบบโต้ตอบหลังจากกำหนดจำนวนวินาที คุณอาจใช้กลไกนั้น

คุณย้ายการล็อกเอาต์โดยการตั้งค่ากับดักตาม (ฉันไม่ได้ทดสอบนั้น) หรือโดยใช้ bash-logout-สคริปต์ (~ / .bash_logout)

นี่คือคำตอบที่ดีสำหรับผู้ใช้ในทิศทางนั้น


สิ่งนี้ไม่ได้ระบุว่าผู้ใช้จะรันคำสั่งอย่างไรแทนที่จะออกจากระบบหลังจาก$TMOUTผ่านไปไม่กี่วินาที
chepner

คุณสามารถเพิ่มข้อมูลเพิ่มเติมในคำตอบของคุณได้หรือไม่? มันยังไม่ชัดเจนสำหรับฉัน ...
IonicăBizău

@chepner ฉันเพิ่มรายละเอียดเพิ่มเติมลงในคำตอบของฉัน
นิลส์

ไม่ว่าจะด้วยวิธีใดวิธีนี้เพียงบันทึกผู้ใช้หลังจากหมดเวลา ฉันไม่คิดว่ามีวิธีการยกเลิกออกจากระบบใด ๆ ทั้งจากกับดักหรือจากEXIT .bash_logout
chepner

3

นี่ไม่ใช่สิ่งที่คุณต้องการ แต่มักจะมีbatchคำสั่ง - (มักจะเป็นการเรียกใช้atคำสั่งพิเศษของatd-command และใช้-daemon)

batchช่วยให้คุณสามารถเรียกใช้คำสั่งเพื่อเรียกใช้เมื่อการปล่อยโหลดเฉลี่ยต่ำกว่าขีด จำกัด ที่แน่นอน (ปกติคือ 1.5 แต่สามารถตั้งค่าได้เมื่อเริ่มต้นatd) ด้วยความatเป็นไปได้ที่จะคิวงานในลักษณะที่แทนที่จะทำงานในช่วงเวลาหนึ่ง งานจะถูกส่งไปยังbatchในเวลานั้นและทำงานครั้งแรกเมื่อหยดเฉลี่ยลดลง (เช่นทำงานทันทีที่หยดเฉลี่ยลดลงต่ำกว่า 1.5 บางครั้งหลังจาก 2:00 น.)

โชคไม่ดีที่งานแบตช์จะสิ้นสุดลง แต่จะไม่หยุดหากคอมพิวเตอร์ไม่ได้ใช้งานอีกต่อไป

+++

หากคุณต้องไปที่เส้นทางการเขียนโปรแกรม (ซึ่งดูเหมือนว่าจากคำตอบอื่น ๆ ) ฉันคิดว่าฉันพยายามทำสิ่งที่คล้ายกับatdหรือcrondภูตที่ตรวจสอบผู้ใช้เข้าสู่ระบบและ / หรือโหลดเฉลี่ย ภูตนี้สามารถเรียกใช้สคริปต์ / โปรแกรมจากไดเรกทอรีที่แน่นอนและเริ่มต้น / ดำเนินการต่อหรือหยุดพวกเขา (พร้อมสัญญาณ) ตามที่ต้องการ


หากคุณทำสิ่งนี้และใช้.lockไฟล์คุณสามารถจัดการกับปัญหาเรื่องเวลาได้อย่างง่ายดาย
mikeserv

2

เธรดนี้มีวิธีแก้ไขปัญหาสองข้อโดยอิงจากการตรวจหากิจกรรมแป้นพิมพ์และเมาส์ ฉันทำงานxprintidleจากงาน cron ซึ่งเริ่มทุกสองสามนาที แต่เนื่องจากสิ่งเหล่านี้ชี้ให้เห็นxprintidleว่าไม่มีการระบายออกดังนั้นคุณอาจต้องการติดตั้งโมดูล Perl และใช้สิ่งนั้นแทน:

$ cpanm X11::IdleTime
...
$ sleep 10; perl -MX11::IdleTime -le 'print GetIdleTime()'
9

ฉันจะใช้วิธีแก้ปัญหาอย่างใดอย่างหนึ่งโดยการสำรวจจาก cron ในสคริปต์ที่ออกจากด้านบนหาก UI ไม่ได้ใช้งานไม่เพียงพอ แน่นอนว่าสคริปต์จะต้องมีexport DISPLAY=:0.0เพื่อพูดคุยกับ X11

โปรดจำไว้ว่าแป้นพิมพ์และเมาส์ของคุณอาจไม่ทำงานเมื่อดูภาพยนตร์หรือใช้งาน CPU มาก


1

ฉันไม่รู้วิธีการทำเช่นนี้หากไม่มีการสำรวจสถานะของระบบบางอย่างเช่นคำตอบอื่น ๆ ที่ใช้สกรีนเซฟเวอร์หรือตัวจับเวลา bash idle หรือเรียกใช้จาก. bash_logout แต่นี่เป็นแนวคิดในการตรวจสอบการใช้งาน CPU

สิ่งนี้จะยังคงเกี่ยวข้องกับการสำรวจทุก ๆ n วินาทีและหากการใช้งาน CPU ของคุณต่ำกว่าจำนวนที่คุณเลือกคุณสามารถสคริปต์สิ่งที่คุณต้องการเรียกใช้ อย่างไรก็ตามสิ่งที่คุณเรียกใช้สามารถยกระดับการใช้งาน CPU แต่คุณสามารถใช้ "สิ่ง" ที่ดีของคุณเพื่อไม่นับ

นี่คือสคริปต์ทดสอบโดยใช้ด้านบน แต่คุณสามารถใช้ mpstat แทนหรือตรวจสอบค่าเฉลี่ยการโหลดแทน

while true
do
idle=$(top -bn2 | grep "Cpu(s)"|tail -n 1|sed "s/.*, *\([0-9.]*\)%* id.*/\1/")
echo "idle is $idle"
if [[ $idle > 90 ]]
then
    echo "idle above 90%"
    echo "Do stuff now"
else
    echo "idle below 90%"
    echo "Stop doing stuff now"
fi
sleep 1
done

นั่นเป็นเพียงสคริปต์ที่ฉันรวมเข้าด้วยกันเพื่อทดสอบการอ่านว่างจากด้านบน คุณสามารถแยกวิเคราะห์ได้/proc/statแต่ฉันคิดว่ามันแสดงเฉพาะเวลารวมทั้งหมดและคุณต้องเปรียบเทียบผลลัพธ์ในช่วงเวลาหนึ่ง ด้านบนมีปัญหาของตัวเองสำหรับฉัน (linux mint 16) ในการรันครั้งแรกดูเหมือนว่าจะไม่เปลี่ยน cpustats ราวกับว่ามันต้องรอการแยกวิเคราะห์ / proc / stat เองดังนั้นtop -bn2ในทางทฤษฎีแล้วtop -bn1ควรทำงาน


เอ่อ ... จริงเหรอ? สำรวจคะแนน CPU หรือไม่
Rolf

อย่างไรก็ตามคุณสามารถสำรวจwคำสั่งที่แสดงเวลาว่างของผู้ใช้ - โดยวิธีการที่ฉันไม่ได้ตัดสินมันเป็นเพียงสำหรับฉันฉันต้องการตรวจจับการไม่ได้ใช้งานเพื่อให้เครื่องนอนหลับเพื่อพลังงานสำรอง
Rolf

@Rolf ฟังดูดีมาก ... เนื่องจากความคิดเห็นนั้นไม่ได้เพิ่มอะไรมากมันน่าจะถูกลบใช่มั้ย? อย่างไรก็ตามคำตอบอื่น ๆ ใช้เวลาว่างในวิธีต่าง ๆ ไม่กี่วิธี แต่คุณจะตรวจจับไม่ได้ใช้งานโดยไม่ต้องดู / ถามระบบได้อย่างไร
Xen2050
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.