How could I set a universal time limit on any command line operation?

Solution 1:

Prefix with shellscript check

The shellscript check, that can be used to prefix any command line may look like this,

#!/bin/bash

if [ "$1" == "--debug" ]
then
 debug=true
 shift
else
 debug=false
fi

"$@" & pid=$!
sleep 0.1  # time (s) until kill
kill $pid 2> /dev/null
res="$?"

if $debug
then
 if [ $res -eq 0 ]
 then
  echo "killed at time-out: $@"
 else
  echo "finished gracefully: $@"
 fi
fi

Example 1

$ ./check --debug bash -c "while true;do date '+%s.%N';sleep 0.01;done"
1634944386.589977656
1634944386.603126888
1634944386.616089924
1634944386.629058026
1634944386.642334480
1634944386.655644267
1634944386.668289318
1634944386.681058710
killed at time-out: bash -c while true;do date '+%s.%N';sleep 0.01;done

Example 2

$ ./check --debug lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0 238,5G  0 disk 
├─sda1        8:1    0   500M  0 part 
├─sda2        8:2    0 139,4G  0 part 
├─sda3        8:3    0  1000M  0 part 
├─sda4        8:4    0     1K  0 part 
├─sda5        8:5    0  89,7G  0 part /
└─sda6        8:6    0     8G  0 part [SWAP]
sdb           8:16   0   3,7T  0 disk 
├─sdb1        8:17   0   510M  0 part 
├─sdb2        8:18   0    30G  0 part 
├─sdb5        8:21   0     1M  0 part 
├─sdb6        8:22   0   100G  0 part 
├─sdb7        8:23   0   3,5T  0 part /media/multimed-2
└─sdb8        8:24   0     5G  0 part 
sr0          11:0    1  1024M  0 rom  
nvme0n1     259:0    0 232,9G  0 disk 
├─nvme0n1p1 259:1    0 232,9G  0 part 
└─nvme0n1p2 259:2    0     1M  0 part 
finished gracefully: lsblk

Primitive custom shell psh

Another alternative, a primitive home-mode shell psh can be used for this purpose too.

  • Advantage: You can run the commands directly without any extra prefix.

  • Disadvantages: You can edit the command line, but there is no history and you have no access to the history of a standard shell, for example bash, zsh, tcsh`). Several other features of a the standard shell are missing too.

The bash shellscript psh and the python3 script pin should be made executable and copied, moved or linked into a directory in PATH, for example /usr/local/bin,

Start psh, run commands and exit from it with exit. The input is managed by pin, that uses readline in order to make it possible to edit the command line (more advanced than the built-in command read of bash).

psh,

#!/bin/bash

tmpf=$(mktemp)
curdir="$(pwd)"
cmd=
while true
do
# read -p "psh:$curdir> " cmd 2>&1
# echo "$cmd" > "$tmpf"
 pin "$curdir" "$tmpf"
#      cat "$tmpf"
 cmd=$(cat "$tmpf")
 if [ "$cmd" != "exit" ]
 then
  if [ "${cmd:0:3}" == "cd " ]
  then
   source "$tmpf"
   curdir="$(pwd)"
  else
   source "$tmpf" & pid=$!
   sleep 0.1  # time (s) until kill
   kill $pid 2> /dev/null
  fi
 else
  break
 fi
done 2> /dev/null
rm "$tmpf"

pin,

#!/usr/bin/python3

from sys import argv
import rlcompleter
import readline
readline.parse_and_bind("tab: complete")
prompt = 'psh:{0} > '.format(argv[1])

f = open(argv[2], 'w')
cmd = input(prompt)
f.write('{0}\n'.format(cmd))  # write to first argument

Example:

sudodus@bionic64 /media/multimed-2/test/test0/temp/PeterElbert $ psh
psh:/media/multimed-2/test/test0/temp/PeterElbert >  while true;do date '+.%N';sleep 0.008;done
.753302869
.763750113
.773720876
.783983502
.794652755
.805570413
.816651252
.827621482
.838553391
.849516607
psh:/media/multimed-2/test/test0/temp/PeterElbert > ls -l
totalt 12
-rwxrwxr-x 1 sudodus sudodus 282 okt 23 01:18 check
-rwxrwxr-x 1 sudodus sudodus 255 okt 23 07:18 pin
-rwxrwxr-x 1 sudodus sudodus 438 okt 23 07:51 psh
psh:/media/multimed-2/test/test0/temp/PeterElbert > cd ..
psh:/media/multimed-2/test/test0/temp > exit
sudodus@bionic64 /media/multimed-2/test/test0/temp/PeterElbert $