การเขียนเซอร์วิส systemd ที่จะดำเนินการเมื่อดำเนินการต่อ


15

แล็ปท็อป Dell ของฉันอยู่ภายใต้ข้อบกพร่องนี้ด้วยเคอร์เนล 3.14 ในฐานะที่เป็นวิธีแก้ปัญหาฉันเขียนสคริปต์ง่าย ๆ

/ usr / bin / สว่างแก้ไข:

#!/bin/bash

echo 0 > /sys/class/backlight/intel_backlight/brightnes

(และทำให้ปฏิบัติการ: chmod +x /usr/bin/brightness-fix)

และบริการ systemd เรียกมันว่าจะดำเนินการเมื่อเริ่มต้น:

/etc/systemd/system/brightness-fix.service

[Unit]
Description=Fixes intel backlight control with Kernel 3.14

[Service]
Type=forking
ExecStart=/usr/bin/brightness-fix
TimeoutSec=0
StandardOutput=syslog
#RemainAfterExit=yes
#SysVStartPriority=99

[Install]
WantedBy=multi-user.target

และเปิดใช้งาน: systemctl enable /etc/systemd/system/brightness-fix.service

มันใช้งานได้อย่างมีเสน่ห์และฉันสามารถควบคุมความสว่างของหน้าจอได้ตามต้องการ ปัญหาเกิดขึ้นเมื่อแล็ปท็อปดำเนินการต่อหลังจากเข้าสู่โหมดสลีป (เช่นเมื่อปิดริมฝีปากแล็ปท็อป): การควบคุมความสว่างไม่ทำงานอีกต่อไปเว้นแต่ฉันจะเรียกใช้สคริปต์ fisrt ด้านบนด้วยตนเอง:/usr/bin/brightness-fix

ฉันจะสร้างบริการ systemd อื่นเช่นของฉันด้านบนเพื่อดำเนินการในเวลาดำเนินการต่อได้อย่างไร?

แก้ไข: ตามความคิดเห็นด้านล่างฉันได้แก้ไขbrightness-fix.serviceเช่นนี้:

[Unit]
Description=Fixes intel backlight control with Kernel 3.14

[Service]
Type=oneshot
ExecStart=/usr/local/bin/brightness-fix
TimeoutSec=0
StandardOutput=syslog

[Install]
WantedBy=multi-user.target sleep.target

ฉันได้เพิ่มecho "$1 $2" > /home/luca/br.logสคริปต์ของฉันเพื่อตรวจสอบว่ามีการดำเนินการจริงหรือไม่ สคริปต์ที่ถูกเรียกใช้งานจริงนั้นยังทำงานต่อ ( post suspend) แต่ไม่มีผลกระทบ (backlit คือ 100% และไม่สามารถเปลี่ยนแปลงได้) ฉันยังลองบันทึก$DISPLAYและ$USERในเวลาที่กลับมาว่างเปล่า ดังนั้นฉันเดาว่าสคริปต์จะถูกดำเนินการเร็วเกินไปเมื่อตื่นจากการนอนหลับ คำใบ้ใด ๆ


2
WantedBy=sleep.target...
jasonwryan

จริงๆ?! นั่นง่ายจัง! :) ฉันสามารถเพิ่ม 'sleep.target' ลงในสคริปต์ของฉันด้านบนหรือฉันจะสร้างสคริปต์บริการ systemd เฉพาะใหม่ได้หรือไม่?
lviggiani

... ตามเอกสาร "ตัวเลือกนี้อาจถูกใช้มากกว่าหนึ่งครั้งหรืออาจให้รายชื่อหน่วยที่คั่นด้วยช่องว่าง" ฉันจะลองตอนนี้
lviggiani

คุณต้องเพิ่มลงในไฟล์เซอร์วิส systemd ที่มีอยู่ของคุณ (ซึ่งไม่ใช่สคริปต์ แต่เป็นไฟล์คอนฟิกูเรชันแบบสแตติก) และเป็นที่ทราบด้านระบบแฟ้ม Hierarchy มาตรฐานระบุว่าสถานที่ที่เหมาะสมที่จะนำสคริปต์ที่คุณเขียนเองไม่ได้/usr/local/bin /usr/binไดเรกทอรีนั้นสงวนไว้สำหรับผู้จัดการแพ็คเกจเท่านั้น
strugee

2
ฉันเชื่อว่าการใช้sleep.targetจะเรียกใช้หน่วยเมื่อคอมพิวเตอร์เข้าสู่โหมดสลีปแทนที่จะทำงานต่อ ดูคำตอบของฉันด้านล่างสำหรับไฟล์หน่วยที่ทำงานให้ฉันด้วยปัญหาที่คล้ายกัน
jat255

คำตอบ:


18

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ไฟล์หน่วยต่อไปนี้ทำงานเพื่อให้ฉันเรียกใช้สคริปต์เมื่อดำเนินการต่อจากโหมดสลีป:

[Unit]
Description=<your description>
After=suspend.target

[Service]
User=root
Type=oneshot
ExecStart=<your script here>
TimeoutSec=0
StandardOutput=syslog

[Install]
WantedBy=suspend.target

ฉันเชื่อว่าเป็นสิ่งAfter=suspend.targetที่ทำให้มันทำงานต่อได้มากกว่าเมื่อคอมพิวเตอร์เข้าสู่โหมดสลีป


4
ทำงานร่วมกับ After=suspend.target ในหน่วยและ WantedBy=multi-user.target sleep.targetในการติดตั้ง
Emmanuel

ฉันใช้หน่วยต่อไปนี้เรียบร้อยแล้วที่นี่บน Ubuntu 16.04 (เบื้องต้น Loki)
Naftuli Kay

7

ในฐานะที่เป็นทางเลือกในการเขียนและการเปิดใช้งานไฟล์หน่วยคุณยังสามารถใส่สคริปต์เชลล์ (หรือ symlink ไปสคริปต์ของคุณ) /lib/systemd/system-sleep/ลงใน

มันจะถูกเรียกก่อนนอน / จำศีลและในเวลาที่ดำเนินการต่อ

จาก man systemd-suspend.service :

ทันทีก่อนที่จะเข้าสู่ระบบ suspend และ / หรือ hibernation systemd-suspend.service (และหน่วยงานอื่น ๆ ที่เกี่ยวข้องตามลำดับ) จะเรียกใช้งาน executables ทั้งหมดใน / usr / lib / systemd / system-sleep / และส่งอาร์กิวเมนต์สองตัว อาร์กิวเมนต์แรกจะเป็น "pre" ส่วนที่สองคือ "suspend", "hibernate" หรือ "hybrid-sleep" ขึ้นอยู่กับการกระทำที่เลือก ทันทีหลังจากออกจากระบบพักและ / หรือไฮเบอร์เนตระบบปฏิบัติการเดียวกันจะทำงาน แต่ตอนนี้อาร์กิวเมนต์แรกคือ "โพสต์" ไฟล์เรียกทำงานทั้งหมดในไดเร็กทอรีนี้ถูกเรียกใช้งานแบบขนานและการดำเนินการของแอ็คชันจะไม่ดำเนินต่อไปจนกว่าไฟล์ประมวลผลทั้งหมดจะเสร็จสิ้น

ทดสอบด้วยสิ่งนี้:

#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/

logger -t "test" "\$0=$0, \$1=$1, \$2=$2"

man page ที่คุณลิงค์กล่าวถึงไฟล์ที่วางไว้/usr/libแต่ตัวอย่างทั้งหมดของคุณอ้างถึงไฟล์ภายใต้/lib
qdii

@qdii: มันอาจขึ้นอยู่กับการกระจายและ / หรือรุ่น ใน Debian 8 Jessie และ Ubuntu 16.04 system-sleepไดเรกทอรีดูเหมือนจะอยู่ใน/lib/systemd/และ/usr/lib/systemdมีสิ่งอื่น ๆ
mivk

1

ติดตามคำตอบของ mivk ซึ่งฉันหลีกเลี่ยงการสร้างไฟล์หน่วยใหม่ (ดูคำถามของฉันที่นี่วิธีตอบสนองต่อเหตุการณ์ฝาแล็ปท็อป? ) นี่คือทางออกของฉัน มันไม่ตรงไปตรงมา 100% ( ถอนหายใจ ) เพราะระบบไม่เสถียรเมื่อออกจากโหมดสลีป:

ในกล่อง Fedora 26 ของฉันฉันใส่ symlink ไว้ที่นี่: /usr/lib/systemd/system-sleep/sleepyheadจุดไหน: /root/bin/sleepyheadซึ่งประกอบด้วย:

#!/bin/sh
## This file (or a link to it) must be in /lib/systemd/system-sleep/

# This is called when the lid is closed, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=pre, $2=suspend
# ...and when the lid is opened, as follows:
# $0=/usr/lib/systemd/system-sleep/sleepyhead, $1=post, $2=suspend


touch /tmp/sleepyrun
logger -t "sleepyhead" "Start: \$1=$1, \$2=$2"
if [ "$1" = "post" ] ; then
    action="RUN trackpoint in background"
    bash /root/bin/trackpoint >/tmp/trackpoint-run 2>&1
else
    action="NO ACTION"
fi
logger -t "sleepyhead" "${action}: " "\$1=$1, \$2=$2"

/root/bin/trackpointสคริปต์ดังต่อไปนี้ โปรดทราบว่าการนอนหลับครั้งแรกมีความสำคัญ มีการตั้งค่าอุปกรณ์ทุกครั้งที่มีการเปิดฝาดังนั้นจึงไม่มีอยู่ในตอนแรก ถ้าฉันพยายามทำอะไรนอกจากสลีปสคริปต์ "sleepyhead" ใช้เวลานานมากในการออกและตัวชี้ของฉันจะถูกตรึงไว้อย่างน้อย 60 วินาที นอกจากนี้โปรดทราบว่าคุณไม่สามารถใส่/root/bin/trackpointสคริปต์ในพื้นหลังsleepyheadด้านบน หากคุณทำเช่นนั้นกระบวนการจะถูกฆ่าเมื่อsleepyheadออก

#!/bin/bash
# This is /root/bin/trackpoint

echo "Start $0"
date

found=false
dir=""
# dirlist can look like:
# /sys/devices/platform/i8042/serio1/serio25/speed
# /sys/devices/platform/i8042/serio1/serio24/speed
# ...the older one appears to get cleaned a little later.

sleep 1 # If I don't put this in here, my pointer locks up for a really long time...
for i in 1 2 3 4; do
    speedfiles=$(find /sys/devices/platform/i8042 -name speed) # There may be multiple speed files at this point.
    [ -z "$speedfiles" ] && { sleep 1; continue; }
    dirlist=$(dirname $speedfiles)
    printf "Speed file(s) at $(find /sys/devices/platform/i8042 -name speed | tail -1) \n"
    # All this remaking of the path is here because the filenames change with
    # every resume, and what's bigger: 9 or 10? ...Depends if you're
    # lexicographical or numerical. We need to always be numerical.
    largest_number="$(echo $dirlist | tr ' ' '\n' | sed -e 's/.*serio//' | sort -n | tail -1)"
    dir="$(echo $dirlist | tr ' ' '\n' | egrep serio${largest_number}\$ )"
    echo "Dir is $dir number is $largest_number" 
    [ -n "$dir" ] && found=true && break
done
$found || exit 1


date
echo -n 4 > $dir/inertia
echo -n 220 > $dir/sensitivity
echo -n 128 > $dir/speed
date
echo "Done $0"

จัดระเบียบอย่างดีและจัดทำเป็นเอกสาร ฉันจะให้คุณหลายคะแนนถ้าทำได้!
MountainX
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.