Discussion:
how to timeout system command?
(too old to reply)
fidokomik
2018-08-03 19:20:37 UTC
Permalink
I need to run some system command on Linux OS, say "sudo mount ..." from Perl Tk script. But in some situations this command wait for user interaction and I want to terminate it with defined timeout. I tried to use alarm(), IPC::Run, IPC::System::Simple but nothing work correctly. I have no other idea how to do it. I must to say too: it will run on Raspbian (Debian like) distribution.

Snippet of my code:

use strict;
use Tk;
...
our $svr='//192.168.1.1/pi';
our $mnt='/mnt/pi';
our $lgn='pi';
our $pwd='pi';
...
$mw->after(50, \&init);
MainLoop;


sub init {
my $x;
$SIG{ALRM} = sub {$x="error TIMEOUT"; die "error mount\n";};
alarm 5;
# next command need to ignore if not success for 5 second
$x=qx(sudo -t cifc mount $svr $mnt -o username=$lgn,password=$pwd,noperm 2>&1);
alarm 0;
if ($x=~/error/) {print "mount fail\n"}
else { # do some ...}
}
Christopher Chavez
2018-08-24 17:09:36 UTC
Permalink
Post by fidokomik
I need to run some system command on Linux OS, say "sudo mount ..." from Perl Tk script. But in some situations this command wait for user interaction and I want to terminate it with defined timeout. I tried to use alarm(), IPC::Run, IPC::System::Simple but nothing work correctly. I have no other idea how to do it. I must to say too: it will run on Raspbian (Debian like) distribution.
use strict;
use Tk;
...
our $svr='//192.168.1.1/pi';
our $mnt='/mnt/pi';
our $lgn='pi';
our $pwd='pi';
...
$mw->after(50, \&init);
MainLoop;
sub init {
my $x;
$SIG{ALRM} = sub {$x="error TIMEOUT"; die "error mount\n";};
alarm 5;
# next command need to ignore if not success for 5 second
$x=qx(sudo -t cifc mount $svr $mnt -o username=$lgn,password=$pwd,noperm 2>&1);
alarm 0;
if ($x=~/error/) {print "mount fail\n"}
else { # do some ...}
}
Would it be possible for you to instead use a command like `pkexec` as a
graphical substitute for `sudo` and avoid needing to timeout?


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
fidokomik
2018-08-24 19:21:52 UTC
Permalink
The user should not see that for many reasons :) User do not speak English, but Raspberry yes, user do not know passwords, user know nothing about LAN.

Generally, I want to run a system command with a defined timeout, and if not success, then run some Perl action or ask the user for basic questions in their language.
Christopher Chavez
2018-09-10 07:59:34 UTC
Permalink
Post by fidokomik
The user should not see that for many reasons :) User do not speak English, but Raspberry yes, user do not know passwords, user know nothing about LAN.
Generally, I want to run a system command with a defined timeout, and if not success, then run some Perl action or ask the user for basic questions in their language.
Some more non-Perl suggestions:

I did come across very hacky ways of timing out a sudo process (though I
do not understand the details), e.g.
https://askubuntu.com/a/401536/549800 . All are with the caveat that
even if sudo does not get stuck waiting for a password, the process to
be run still gets killed after the timeout.

There is also the passwd_timeout option in the sudoers file, if you have
control over that.


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

Christopher Chavez
2018-09-10 07:50:37 UTC
Permalink
Post by fidokomik
I need to run some system command on Linux OS, say "sudo mount ..." from Perl Tk script. But in some situations this command wait for user interaction and I want to terminate it with defined timeout. I tried to use alarm(), IPC::Run, IPC::System::Simple but nothing work correctly. I have no other idea how to do it. I must to say too: it will run on Raspbian (Debian like) distribution.
use strict;
use Tk;
...
our $svr='//192.168.1.1/pi';
our $mnt='/mnt/pi';
our $lgn='pi';
our $pwd='pi';
...
$mw->after(50, \&init);
MainLoop;
sub init {
my $x;
$SIG{ALRM} = sub {$x="error TIMEOUT"; die "error mount\n";};
alarm 5;
# next command need to ignore if not success for 5 second
$x=qx(sudo -t cifc mount $svr $mnt -o username=$lgn,password=$pwd,noperm 2>&1);
alarm 0;
if ($x=~/error/) {print "mount fail\n"}
else { # do some ...}
}
For mounts specifically, I would suggest using a modern and/or
FUSE-based approach for non-root users, and avoid sudo as a side effect.
I.e. a command like `gio mount "smb://..."` (used to be `gvfs-mount`
until recently). It's somewhat more complicated if other user on the
system (including root) needs access to the mount though.


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
Loading...