Repository navigation
Expand file tree
/
Copy pathshell-api-sys.sh
More file actions
423 lines (356 loc) · 10.4 KB
/
Copy pathshell-api-sys.sh
File metadata and controls
423 lines (356 loc) · 10.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
#!/bin/bash
###############################################################################
#
# Copyright (c) 2024 Michel Mehl. All rights reserved.
#
# -----------------------------------------------------------------------------
#
# A shell API related to low-level system functions.
#
# -----------------------------------------------------------------------------
#
# Report bugs to michel.mehl@slashetc.fr
#
###############################################################################
__SHELL_API_SYS_DIR__=$(readlink -f $(dirname ${BASH_SOURCE[0]}))
source "${__SHELL_API_SYS_DIR__}/shell-api-core.sh"
if _loaded "${BASH_SOURCE[0]}" ; then
return 0
fi
:<<'EOF'
Returns PID of current running script
Beware not to call this from a subshell (e.g with notation $(...)), otherwise
the PID of the temporary subshell is returned!
@param [1] out reference of the variable where to store the PID
EOF
Sys__getPID()
{
if [ $# -eq 1 ] ; then
local -n out_pid=$1
out_pid=$$
else
_log_warn "${FUNCNAME[0]}: missing variable name reference argument."
fi
}
:<<'EOF'
Waits for the process of the given PID to end. If input PID is 0, nothing is done.
@param [1] inout ref to the variable containing the PID. If process ended, variable value is reset to 0
@returns return value of low level 'wait', that is the exit code of the process normally.
If input PID is 0, nothing is done and 0 is returned.
EOF
Sys__wait()
{
if ! Args__checkCount ${FUNCNAME[0]} 1 "$#" "Usage: <ref to var containing PID>"; then
return 1
fi
local -n __out_pid=$1
if [ $__out_pid -eq 0 ] ; then
return 0
fi
local ret
wait $__out_pid
ret=$?
__out_pid=0
return $ret
}
:<<'EOF'
Spawns a process in background and stores the PID in passed var.
@param [1] out ref to the variable that will contain the PID of launched process.
@param [2] the command to launch and all its arguments
NOTE: spawn now executes directly the passed arguments with calling eval. However, this latter option might still be useful e.g. there would be some arguments to interpret
@returns return 0 on success only.
EOF
Sys__spawn()
{
if ! Args__checkMinCount ${FUNCNAME[0]} 2 "$#" "Usage: <ref to var containing PID> <command> <args>"; then
return 1
fi
local -n __out_pid=$1
shift
#echo "Sys__spawn avec args $# '$@' " # DEBUG
"$@" &
#eval "$@" &
__out_pid=$!
return 0
}
Sys__gspawn_init()
{
Sys__global_pid_file="$1/.sys__global_gids.txt"
}
:<<'EOF'
Spawns a process in background and stores the PID in the global array 'Sys__global_pid'
@param [1] the command to launch
@returns return 0 on success only.
EOF
Sys__global_pid_file=".sys__global_gids"
Sys__gspawn()
{
if ! Args__checkMinCount ${FUNCNAME[0]} 1 "$#" "Usage: <command> <args>"; then
return 1
fi
local pid
local spawnArgs=()
while [ $# -gt 0 ] ; do
#_log "spawnArgs $1" >&2
spawnArgs+=("$1")
shift
done
Sys__spawn pid "${spawnArgs[@]}"
#Sys__spawn pid "$@"
if [ $? -eq 0 ] ; then
#Sys__global_pid+=($pid)
Sys__addGlobalPid "$pid"
return 0
else
return 1
fi
}
:<<'EOF'
Waits for all processes which pid is stored in the global array 'Sys__global_pid' to wait,
and the clear that arraY.
EOF
Sys__gwait()
{
#if [ ${#Sys__global_pid[@]} -gt 0 ] ; then
_logf "${FUNCNAME[0]}: WAIING FOR PROCESSES ${Sys__global_pid[@]}"
exec 9> /var/lock/sys__global_gids.lock
if ! flock -x -w 10 9; then
return 1
fi
local configPath="${Sys__global_pid_file}"
if [ -f "$configPath" ] ; then
local globalPids
read globalPids< <(cat "$configPath")
echo > "$configPath"
Str__trim "$globalPids" globalPids
#_log "Sys__gwait: waiting for processes ${globalPids}"
fi
flock -u 9
exec 9>&-
if [ ! -z "${globalPids}" ] ; then
wait ${globalPids}
lastStatus=$?
fi
_logf "${FUNCNAME[0]}: END WAIING"
return $lastStatus
#Sys__global_pid=()
#fi
}
Sys__addGlobalPid()
{
local pid="$1"
local configPath="${Sys__global_pid_file}"
#_log "Sys__addGlobalPid adding pid '$pid' to file '$configPath'"
(
flock -w 10 9 || return 1
echo -n "${pid} " >> "$configPath"
sync "$configPath"
) 9>/var/lock/sys__global_gids.lock
}
Sys__pool_init()
{
local name="$2"
local size=$3
local -n __inout_pool=$1
__inout_pool[0]="$name"
__inout_pool[1]=$size
Sys__pool_reset __inout_pool
#_log "${FUNCNAME[0]}: init done for ${__inout_pool[0]} of size ${__inout_pool[1]}"
}
Sys__pool_reset()
{
local -n __inout_pool_reset=$1
local size=${__inout_pool_reset[1]}
if [ -z "$size" ] ; then
_log_err "${FUNCNAME[0]}: Invalid pool passed. No pool size value stored in \${pool[1]}."
return 1
fi
size=$(($size+2))
local c=2
while [ $c -lt $size ] ; do
__inout_pool_reset[c]="x"
c=$(($c+1))
done
#_log "${FUNCNAME[0]}: reset done for ${__inout_pool_reset[0]} of size ${__inout_pool_reset[1]}"
}
Sys__pool_pid_list()
{
local -n __in_pool_list=$1
local -n __out_pidlist=$2
local size=${__in_pool_list[1]}
if [ -z "$size" ] ; then
_log_err "${FUNCNAME[0]}: Invalid pool passed. No pool size value stored in \${pool[1]}."
return 1
fi
size=$(($size+2)) # 2 first are name and size
local c=2
while [ $c -lt $size ] ; do
# Take the first free
if [ ${__in_pool_list[$c]} != "x" ] ; then
__out_pidlist+=(${__in_pool_list[$c]})
fi
c=$(($c+1))
done
return 0
}
Sys__pool_pid_print()
{
local -n __inout_pool_print=$1
local message="$2"
local pidlist=()
Sys__pool_pid_list __inout_pool_print pidlist
echo "$message: ${pidlist[@]}"
}
Sys__pool_spawn()
{
# echo "START ++ Sys__pool_spawn avec args $# '$*'"
local -n __inout_pool_spawn=$1
local size=${__inout_pool_spawn[1]}
shift # Shift to the command to launch
if [ -z "$size" ] ; then
_log_err "${FUNCNAME[0]}: Invalid pool passed. No pool size value stored in \${pool[1]}."
return 1
fi
local spawnArgs=()
while [ $# -gt 0 ] ; do
#_log "spawnArgs $1" >&2
spawnArgs+=("$1")
shift
done
size=$(($size+2)) # 2 first are name and size
local c=2
while [ $c -lt $size ] ; do
# Take the first free
if [ ${__inout_pool_spawn[$c]} == "x" ] ; then
local pid=0
#echo "Sys__pool_spawn avec args '$@'"
Sys__spawn pid "${spawnArgs[@]}"
#Sys__spawn pid "$@"
if [ $pid -ne 0 ] ; then
#_log "${FUNCNAME[0]}: launched $pid on slot $c"
__inout_pool_spawn[$c]=$pid
return 0
fi
fi
c=$(($c+1))
done
Sys__pool_waitall __inout_pool_spawn
# Take the first freed
local c=2
while [ $c -lt $size ] ; do
if [ ${__inout_pool_spawn[$c]} == "x" ] ; then
local pid=0
Sys__spawn pid "${spawnArgs[@]}"
#Sys__spawn pid "$@"
if [ $pid -ne 0 ] ; then
#_log "${FUNCNAME[0]}: launched $pid on slot $c after a waitall"
__inout_pool_spawn[$c]=$pid
return 0
fi
fi
c=$(($c+1))
done
_log_warn "${FUNCNAME[0]}: ${__inout_pool_spawn[0]} of size ${__inout_pool_spawn[1]} is full. waiting for current pool to finish"
return 1
}
Sys__pool_waitall()
{
local -n __inout_pool_waitall=$1
local pidlist=()
local lastStatus=0
Sys__pool_pid_list __inout_pool_waitall pidlist
#_log "${FUNCNAME[0]}: wait for pid : ${pidlist[@]}"
wait ${pidlist[@]}
lastStatus=$?
Sys__pool_reset __inout_pool_waitall
return $lastStatus
}
Sys__pool_sweepall()
{
local -n __inout_pool_swipeall=$1
local pidlist=()
local lastStatus=0
Sys__pool_pid_list __inout_pool_swipeall pidlist
#_log "${FUNCNAME[0]}: killing pid : ${pidlist[@]}"
kill -s 9 ${pidlist[@]} &>/dev/null
lastStatus=$?
Sys__pool_reset __inout_pool_swipeall
return $lastStatus
}
:<<'EOF'
Tells whether the process of the passed PID is alive by sending signal 0
@return 0 if kill was ok (alive), another value otherwise
EOF
Sys__isAlive()
{
kill -s 0 "$1" 2>/dev/null
}
:<<'EOF'
Terminates the process of the passed PID by sending signal TERM (15)
@return 0 if termination was ok, another value otherwise (no such process)
EOF
Sys__terminate()
{
kill -s 15 "$1" 2>/dev/null
}
:<<'EOF'
Terminates all processes which process name matches the passed first argument. An additional string filter can be passed to search for in the ps output which is 'pid comm cmd' (comm is the process name)
@param[1] process name
@param[2] addition string filter
EOF
Sys__sweep()
{
if ! Args__checkCount ${FUNCNAME[0]} 2 "$#" "Usage: <proc name> <argument filter>"; then
return 1
fi
local pids
pids=$(ps -ha -o pid,comm,cmd| awk -F' ' -v procname="$1" -v argfilter="$2" '{
if ($2 == procname)
{
#print "OK",$2,procname, argfilter,$3
idx=index($0,argfilter)
if (idx > 0)
{
print $1
}
}
}')
local pidsA=($pids)
#_log "Sys__sweep: '$pids'"
if [ ${#pidsA[@]} -gt 0 ] ; then
#echo kill ${pidsA[@]}
kill -15 ${pidsA[@]}
#else
#_log "nothing to sweep for $1,$2"
fi
}
gnome__setScreenKeyboardVisibile()
{
gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled $1
}
Screen__getResolution()
{
local -n __out_x=$1
local -n __out_y=$2
read __out_x __out_y < <(xrandr --current | grep -oP '\d+x\d+' | tr x ' ')
}
Desktop__getResolution()
{
local -n __out_x=$1
local -n __out_y=$2
read __out_x __out_y < <(wmctrl -d|awk -F' ' '{ if ($2=="*") print $4;}'|tr x ' ')
}
# Note wmctrl -d returns the dimension of the whole desktop
Desktop__isAvailable()
{
_loadDep "net-tools"
${__SUDO__}netstat -lp | grep -i Xorg &>/dev/null
}
CPU__model()
{
local -n __out_cpuModel=$1
local __cpumodel
#read -r __cpumodel < <(lscpu -J| jq -r '.lscpu[]|select(.field=="Model name:")'.data)
read -r __cpumodel < <(lscpu|awk -F':' '{ if ($1 == "Model name") print $2}')
__out_cpuModel="${__cpumodel}"
}