Does anyone know how to do this reliably in Manjaro?:
Setup a binary that needs SU permissions to run at Startup (Manjaro KDE Plasma).
The binary has to access the RPI’s GPIO pins and works when executed with SUDO.
Does anyone know how to do this reliably in Manjaro?:
Setup a binary that needs SU permissions to run at Startup (Manjaro KDE Plasma).
The binary has to access the RPI’s GPIO pins and works when executed with SUDO.
Hi @DrAV,
I do something similar.
You can allow per-binary execution with sudo
with a custom entry in sudoers
.
It’s actually not that hard. The way I did it:
etc/sudoers.d
for the configuration. This way it doesn’t mess with the ‘/etc/sudoers’ file.visudo /etc/sudoers.d/mirdarthos
(I changed my visudo
to use the micro
editor, so can’t really tell you which steps would exactly be neccessary for the rest.)
sudoers
file to allow the execution of a single file with sudo
without requiring a password:<username> ALL=(ALL) NOPASSWD: <full/path/to/script>
Where:
<username>
: The name of the user executing the script. For me, it was mirdarthos, as I’d be the one executing the script.<full/path/to/script>
: The full path to the executable that should be allowed to run as root.You should now, at least theoretically, bee able to tun <full/path/to/script>
using sudo
without entering a password:
sudo <full/path/to/script>
You can then add it to run on startup and it won’t require a password.
At least that’s the theory. If it works, feel free to heap on the praise. However, if it doesn’t, well, then I’m off for the day.
Hi Midarthos, please tell me the steps involved with that editor of yours and where I can get it from as visudo does not appear on my machine:
visudo: no editor found (editor path = /usr/bin/vi)
[fat@RPI4 sudoers.d]$
Hi @DrAV,
visudo
is not an editor. Rather, it’s a command. That makes editing sudoers files safe. You can also use nano
. (In fact, that might be easier, so I’ll explain that here.)
nano
should be installed by default, but to check run the following in the terminal:
pamac search nano
If it is installed, it should be similar to mine:
[...]
nano [Installed] 5.9-1 core
Notice the [Installed]
there.
If it’s not installed, install it with:
pamac install nano
To change the editor to nano
, add the following to /etc/environment
:
# a Custom editor for visudo
SUDO_EDITOR=/usr/bin/nano
This will require administrative rights, but polkit should prompt you for the password if required. I think.
After this, it might be a good idea to restart and try the steps again, from where you got the error.
Edit:
And I’ve got to run now, so if you still need help, try googling for the problem, or wait, hope and pray someone can help you further. Because, it being me, there might be (a) better way(s) to do it. I don’t know, this is just what I’ve got here.
Further reading: Sudo - ArchWiki
Managed to do it using visudo (had to escalate the terminal to root and used visudo from there).
And it runs without entering the password
I’m adding it to the Autostart GUI and will let you know if it runs automatically when I reboot.
OK all works now!
The script is below in case anyone else wants to run a fan from a GPIO pin; just need GCC to compile it to a binary, add it to a file in sudoers.d (as explained above), then add it to the autostart using the GUI with sudo in front of the filename to execute with root privileges. I use an IRLU2703 nMOSFET.
Many thanks,
DrAV
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define IN 0
#define OUT 1
#define LOW 0
#define HIGH 1
static int
GPIOExport(int pin)
{
#define BUFFER_MAX 3
char buffer[BUFFER_MAX];
ssize_t bytes_written;
int fd;
fd = open("/sys/class/gpio/export", O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open export for writing!\n");
return(-1);
}
bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
write(fd, buffer, bytes_written);
close(fd);
return(0);
}
static int
GPIOUnexport(int pin)
{
char buffer[BUFFER_MAX];
ssize_t bytes_written;
int fd;
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open unexport for writing!\n");
return(-1);
}
bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
write(fd, buffer, bytes_written);
close(fd);
return(0);
}
static int
GPIODirection(int pin, int dir)
{
static const char s_directions_str[] = "in\0out";
#define DIRECTION_MAX 35
char path[DIRECTION_MAX];
int fd;
snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);
fd = open(path, O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open gpio direction for writing!\n");
return(-1);
}
if (-1 == write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3)) {
fprintf(stderr, "Failed to set direction!\n");
return(-1);
}
close(fd);
return(0);
}
static int
GPIORead(int pin)
{
#define VALUE_MAX 30
char path[VALUE_MAX];
char value_str[3];
int fd;
snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open gpio value for reading!\n");
return(-1);
}
if (-1 == read(fd, value_str, 3)) {
fprintf(stderr, "Failed to read value!\n");
return(-1);
}
close(fd);
return(atoi(value_str));
}
static int
GPIOWrite(int pin, int value)
{
static const char s_values_str[] = "01";
char path[VALUE_MAX];
int fd;
snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_WRONLY);
if (-1 == fd) {
fprintf(stderr, "Failed to open gpio value for writing!\n");
return(-1);
}
if (1 != write(fd, &s_values_str[LOW == value ? 0 : 1], 1)) {
fprintf(stderr, "Failed to write value!\n");
return(-1);
}
close(fd);
return(0);
}
//Fan MOSFET Gate on GPIO 14 (change POUT to your pin); MOSFET Drain to fan's negative wire; MOSFET Source to GND; Fan positive wire to +5 VDC
#define POUT 14
//Define how often it will check the temperature (in seconds)
#define ttime 5
int main(int argc, char *argv[])
{
FILE *fp;
int temp = 0;
//Enable GPIO pins
if (-1 == GPIOExport(POUT) ) return(1);
usleep(10000);
//Set GPIO direction
if (-1 == GPIODirection(POUT, OUT)) return(2);
usleep(10000);
while(1){
fp = fopen("/sys/class/thermal/thermal_zone0/temp", "r");
fscanf(fp, "%d", &temp);
temp = temp/1000.0;
//Uncomment next line if you want to see the temperature printed in a terminal window
//printf(">> CPU Temp: %.2f°C\n", temp);
fclose(fp);
if(temp>65){
//Write GPIO value
if (-1 == GPIOWrite(POUT, 1)){
return(3);
usleep(10000);
}
}
if (temp<56){
if (-1 == GPIOWrite(POUT, 0)){
return(3);
usleep(10000);
}
}
sleep(ttime);
}
//Disable GPIO pins
if (-1 == GPIOUnexport(POUT)) return(4);
return(0);
}
This is not the proper way to set values in /etc/environment
In the file itself at the top it states:
# Syntax: simple "KEY=VAL" pairs on separate lines
So they should look like this:
EDITOR=/usr/bin/micro
SUDO_EDITOR=/usr/bin/micro
VISUAL=/usr/bin/kate
DIFFPROG=/usr/bin/meld
Thank you! Updated the post as well.
This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.