mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-03 00:56:22 +00:00
lxc-ps: use posix shell and awk instead of bash
Use awk to parse the output pf 'ps' and the tasks files for the containers. Use awk fields to find PID column rather than assume that the PID field is exactly 5 chars wide and has a leading space ' PID'. This works as long as the PID field is before the command or other field that include spaces. This also makes it work with busybox 'ps'. Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> Acked-by: Stéphane Graber <stgraber@ubuntu.com>
This commit is contained in:
parent
600faead38
commit
b5dec5f30b
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# lxc: linux Container library
|
||||
@ -56,16 +56,16 @@ get_parent_cgroup()
|
||||
init_cgroup=${fields#*:}
|
||||
|
||||
# Get the filesystem mountpoint of the hierarchy
|
||||
mountpoint=$(grep -E "^cgroup [^ ]+ [^ ]+ ([^ ]+,)?$subsystems(,[^ ]+)? " /proc/self/mounts | cut -d ' ' -f 2)
|
||||
mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \
|
||||
'$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts)
|
||||
if [ -z "$mountpoint" ]; then continue; fi
|
||||
|
||||
# Return the absolute path to the containers' parent cgroup
|
||||
# (do not append '/lxc' if the hierarchy contains the 'ns' subsystem)
|
||||
if [[ ",$subsystems," == *,ns,* ]]; then
|
||||
parent_cgroup="${mountpoint}${init_cgroup%/}"
|
||||
else
|
||||
parent_cgroup="${mountpoint}${init_cgroup%/}/lxc"
|
||||
fi
|
||||
case ",$subsystems," in
|
||||
*,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";;
|
||||
*) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";;
|
||||
esac
|
||||
break
|
||||
done
|
||||
}
|
||||
@ -97,46 +97,62 @@ if [ ! -d "$parent_cgroup" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
declare -a container_of_pid
|
||||
container_field_width=9
|
||||
IFS=","
|
||||
if [ -z "$containers" ]; then
|
||||
containers=( $(find $parent_cgroup -mindepth 1 -maxdepth 1 -type d -printf "%f," 2>/dev/null) )
|
||||
else
|
||||
containers=( $containers )
|
||||
containers="$(find $parent_cgroup -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::')"
|
||||
fi
|
||||
|
||||
declare -i pid
|
||||
IFS=$'\n'
|
||||
for container in ${containers[@]}; do
|
||||
container_field_width=9
|
||||
tasks_files=
|
||||
for container in ${containers}; do
|
||||
if [ "${#container}" -gt "$container_field_width" ]; then
|
||||
container_field_width=${#container}
|
||||
fi
|
||||
|
||||
if [ -f "$parent_cgroup/$container/tasks" ]; then
|
||||
while read pid; do
|
||||
container_of_pid[$pid]=$container
|
||||
done < "$parent_cgroup/$container/tasks"
|
||||
tasks_files="$tasks_files $parent_cgroup/$container/tasks"
|
||||
fi
|
||||
done
|
||||
|
||||
declare -i line_pid_end_position
|
||||
while read line; do
|
||||
if [ -z "$line_pid_end_position" ]; then
|
||||
if [[ "$line" != *" PID"* ]]; then
|
||||
echo "$(basename $0): no PID column found in \`ps' output" >&2
|
||||
exit 1
|
||||
fi
|
||||
# first file is stdin, the rest are the container tasks
|
||||
ps "$@" | awk -v container_field_width="$container_field_width" '
|
||||
# first line is PS header
|
||||
NR == 1 {
|
||||
# find pid field index
|
||||
for (i = 1; i<=NF; i++)
|
||||
if ($i == "PID") {
|
||||
pididx = i
|
||||
break
|
||||
}
|
||||
if (pididx == "") {
|
||||
print("No PID field found") > "/dev/stderr"
|
||||
exit 1
|
||||
}
|
||||
header = $0
|
||||
next
|
||||
}
|
||||
|
||||
buffer=${line%" PID"*}
|
||||
let line_pid_end_position=${#buffer}+4
|
||||
printf "%-${container_field_width}s %s\n" "CONTAINER" "$line"
|
||||
continue
|
||||
fi
|
||||
# store lines from ps with pid as index
|
||||
NR == FNR {
|
||||
ps[$pididx] = $0
|
||||
next
|
||||
}
|
||||
|
||||
buffer=${line:0:$line_pid_end_position}
|
||||
pid=${buffer##* }
|
||||
if [ "$list_container_processes" -eq "0" -o ! -z "${container_of_pid[pid]}" ]; then
|
||||
printf "%-${container_field_width}s %s\n" "${container_of_pid[pid]}" "$line"
|
||||
fi
|
||||
done < <(ps "$@")
|
||||
# find container name from filename on first line
|
||||
FNR == 1 {
|
||||
container = FILENAME
|
||||
sub(/\/tasks/, "", container)
|
||||
sub(/.*\//, "", container)
|
||||
}
|
||||
|
||||
# container tasks
|
||||
{
|
||||
container_of_pid[$0] = container
|
||||
}
|
||||
|
||||
END {
|
||||
printf("%-" container_field_width "s %s\n", "CONTAINER", header)
|
||||
for (pid in container_of_pid)
|
||||
printf("%-" container_field_width "s %s\n", container_of_pid[pid], ps[pid])
|
||||
}
|
||||
|
||||
' - $tasks_files
|
||||
|
Loading…
Reference in New Issue
Block a user