Comment écrire un script qui modifie le fichier de luminosité dans / sys / class / backlight / ideapad /?

Dec 19 2020

J'utilise i3 wm et j'ai mon fichier de luminosité /sys/class/backlight/ideapad/brightness.

╰─$ ls -la /sys/class/backlight/ideapad/

-rw-r--r-- 1 root root 4096 Dec 18 16:55 brightness

Quand je veux changer la luminosité (disons à 4) je fais:

sudo sh -c "echo 4 > /sys/class/backlight/ideapad/brightness"

Je voudrais écrire un script qui augmenterait ou diminuerait la luminosité de 1, puis lierait ce script à une combinaison de touches dans le fichier de configuration i3 wm ( CTRL+F1par exemple) afin que je puisse contrôler la luminosité en appuyant sur les touches au lieu d'éditer le fichier de luminosité manuellement chaque fois que je souhaite modifier la luminosité.

Étant donné que cela nécessite le privilège root, je ne sais pas comment y parvenir. Dois-je changer mon utilisateur en tant que propriétaire du brightnessfichier ou dois-je simplement changer le groupe du fichier? Ou toute autre façon de penser?

Réponses

1 Quasímodo Dec 19 2020 at 19:30

/sysest un système de fichiers virtuel basé sur la RAM , donc la modification de l'autorisation de ses fichiers ne survivra pas à un redémarrage.

Ce programme C est la solution que j'ai écrite il y a quelque temps et ne m'a jamais déçu. Il ne nécessite rien qu'un système Linux standard ne possède.

#include <stdlib.h>
#include <stdio.h>
#define BUFSIZE 10

int main(int argc, char **argv) {
  FILE *fp;
  char scurr[BUFSIZE];
  long new, curr, incr, min = 10;

  /* An argument with an integer increment must be supplied */
  if (argc != 2 || (incr = strtol(argv[1], NULL, 10)) == 0) { return(1); }

  /* Retrieve the current brightness and increment it in the brightness file */
  if ((fp = fopen("/sys/class/backlight/ideapad/brightness", "r+")) 
      && fgets(scurr, BUFSIZE, fp)) {
    curr = strtol(scurr, NULL, 10);
    rewind(fp);
    new = curr + incr;
    if (new < min) { new = min; }
    fprintf(fp, "%ld\n", new);
    fclose(fp);
  } else { return(2); }

  return(0);
}

Compilez-le ( br.cest le nom du fichier, brl'exécutable), faites root le propriétaire, activez le bit setuid et placez l'exécutable quelque part dans votre PATH( /usr/local/bin/c'est un choix typique).

cc br.c -o br
chown root br
chmod u+s  br
mv br /usr/local/bin/

Maintenant, le simple fait d'exécuter br -100diminue votre luminosité de 100.

Vérifiez que j'ai également défini la luminosité minimale sur min = 10. C'est assez bas sur ma machine que l'on remarque à peine que l'écran est allumé. Ajustez cette valeur en fonction de vos besoins. De plus, pour de nombreuses personnes, le composant de chemin sera quelque chose comme à la intel-backlightplace de ideapad.


Approche alternative

Setuid donne brtous les droits root. Bien que cela ne soulève pas d'exploits dans ce programme particulier, si vous voulez être très prudent et ne lui donner que le jeu de privilèges nécessaire - à savoir, contourner la vérification des autorisations de fichiers -, remplacez les lignes chownet chmodci-dessus par la capacité appropriée

setcap cap_dac_override+ep br
1 ArkadiuszDrabczyk Dec 19 2020 at 00:45

Changer la propriété du groupe est généralement la voie à suivre, mais notez que vous devrez le faire à chaque fois après le redémarrage. Pour ce faire, créez automatiquement une règle udev comme décrit sur le wiki Arch :

Par défaut, seul root peut changer la luminosité par cette méthode. Pour permettre aux utilisateurs du groupe vidéo de modifier la luminosité, une règle udev telle que la suivante peut être utilisée:

/etc/udev/rules.d/backlight.rules

ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="acpi_video0", GROUP="video", MODE="0664"

Si vous n'êtes pas membre du videogroupe, ajoutez-y votre utilisateur:

sudo gpasswd video -a $(whoami)

Notez que vous vous êtes déconnecté et reconnecté pour actualiser les informations d'appartenance au groupe:

su -l $(whoami)

Vérifiez si vous êtes membre du videogroupe avec un identifiant, il devrait afficher quelque chose comme:

$ id
uid=1000(ja) gid=100(users) groups=100(users),16(dialout),17(audio),18(video),83(plugdev),215(vboxusers),281(docker)

Bien sûr, vous pouvez utiliser n'importe quel groupe dont votre utilisateur est membre dans udev rule, pas nécessairement video.