如何为任何命令行操作设置通用时间限制?

如何为任何命令行操作设置通用时间限制?

我想在操作系统深处的某个地方指定,任何运行时间超过指定时间的命令行命令都应自动终止或取消并返回到 shell 提示符。

它必须是通用的并且深入终端系统,以便其他应用程序无法控制命令行并且不受限制的约束。

我怎样才能做到这一点?

具体原因是个人原因,如果我解释原因会听起来很奇怪,但明确的目标是我不希望任何命令行进程花费超过很短的时间,理想情况下是十分之一秒或看似立即的时间。我想强制我的计算从短进程构建,并将我需要执行的所有进程调整到短时间内。如果某个进程花费的时间比这个长,我必须找到一种方法来替换它或以某种方式调整我的系统以使其满足时间限制。如果后台有进程在运行,我永远不需要查看或考虑,那很好。它应该是我在 shell 提示符下看到并执行的命令。

我想在 Ubuntu Server 上执行此操作,因此我不会运行 GUI。我使用 21.04,但版本号对我来说并不重要。

像这样:

$ ls            # returns in .05 seconds
Documents
MyFiles
file.txt

$ python3 myscript.py     # returns in .09 seconds
This is the output of the Python script.

$ wget url            # went for .1 seconds whereupon the operating system terminated it
PROCESS TERMINATED DUE TO TIME LIMIT

答案1

以 shellscript 为前缀check

check可用于作为任​​何命令行前缀的shellscript可能如下所示,

#!/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

示例 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

示例 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

原始定制外壳psh

另一种选择是,原始的家庭模式 shellpsh也可用于此目的。

  • 优点:您可以直接运行命令,无需任何额外的前缀。

  • 缺点:您可以编辑命令行,但没有历史记录,并且您无法访问标准 shell 的历史记录,例如bash,zsh ,tcsh')。标准 shell 的其他几个功能也缺失。

应将bash shellscriptpsh和 python3 脚本pin设为可执行文件,并将其复制、移动或链接到目录中PATH,例如/usr/local/bin

使用启动psh,运行命令并退出exit。输入由 管理pin,使用readline以便可以编辑命令行(比 的内置命令更高级readbash

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

例子:

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 $ 

相关内容