parent-process-output.md 3.7 KB

% Parent process output

Tags

How to find comment trouver

parent process pid parent process terminal

Introduction

Comment trouver la sortie standard (ou d'erreur) d'un processus parent ?

Codes

Approche 1: en analysant les PPID

parent_process_output(){
	local output
	if [[ -z "${1}" ]]
	then
		output=/dev/stderr
	else
		output=$1
	fi
	if [[ -t $output ]]
	then
		#echo "STDERR is opened in terminal"
		:
	else
		#echo "STDERR is NOT opened in terminal"
		if [[ -e $output ]]
		then
			#ls -l $output
			if [[ -L $output ]]
			then
				parent_process_output $(readlink $output)
			else
				echo $output
			fi
		else
				echo $output
		fi
	fi
}
parent_process_output

parent_process_terminal(){
	local ppid
	if [[ -z "${1}" ]]
	then
		ppid=$(ps --pid $$ -o ppid=  | xargs)
	fi
	parent_term=$(readlink /proc/${ppid}/fd/2)
	echo "${ppid}> $parent_term"
	if [[ -c "${parent_term}" ]]
	then
		if [[ "${parent_term}" = "/dev/null" && ! "${parent_term}" =~ ^socket:.* ]]
		then
			parent_process_terminal $(ps --pid ${ppid} -o ppid=  | xargs)
		else
			echo ${parent_term}
		fi
	else
		if [[ $ppid -gt 1 ]]
		then
			parent_process_terminal $(ps --pid ${ppid} -o ppid=  | xargs)
		else
			echo /dev/stderr
		fi
	fi
}
parent_process_terminal

Approche 2 : en analysant l'appelant

Fonctionne avec systemctl

echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
ps -elf | grep 'systemctl' | grep -v grep | awk '{print $13}' | sort -u | while read term ; do echo "$term"; lsof /dev/$term ; echo ; echo "TEST:$term" > /dev/$term ; done
echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"

Le code complet:


has_parent_process(){
	local parent_to_search
	local ppid
	parent_to_search="${1:-}"
	if [ -z "${parent_to_search:-}" ]
	then
		echo "ERROR: need parent process pid as first arg" >&2
		return 5
	fi
	local pid
	pid="${2:-}"
	if [ -z "${pid:-}" ]
	then
		pid=$$
	fi
	if [ $parent_to_search = $pid ]
	then
		echo ${parent_to_search}
		return 0
	else if [ $pid > 1 ]
		then
			ppid=$(ps --pid ${pid} -o ppid= | xargs)
			if [ $ppid = $pid ]
			then
				echo "ERROR: pid=$pid is the same as ppid=$ppid" >&2
				echo -1
			else
				has_parent_process ${parent_to_search} ${ppid}
			fi
		else
			echo "NOT FOUND: ${parent_to_search}" >&2
			echo 1
		fi
	fi
	return 1
}

find_pid_user_of(){
	local used_file=$1
	local regex="$2"
	lsof ${used_file} | awk 'NR>1 && $1 ~ /'${regex}'/ && !($2 in a){a[$2]++; print $2}'
}

find_systemctl_pids(){
	ps -elf | grep 'systemctl' | grep -v grep | awk '{print $13}' | sort -u | while read term
	do
		#echo "$term ---"
		#lsof /dev/$term
		#lsof -F 'cp' /dev/$term
		#echo "$term >>>"
		#lsof /dev/$term | awk 'NR>1 && $1 ~ /.*sh$/ && !($2 in a){a[$2]++; print $2}'
		if [ -z "${shell_pid:-}" ]
		then
			shell_pid=$(find_pid_user_of /dev/$term '.*sh$')
		fi
		if [ -z "${systemctl_pid:-}" ]
		then
			systemctl_pid=$(find_pid_user_of /dev/$term 'systemctl')
		fi
		#echo "shell_pid=$shell_pid" >&2
		#echo "systemctl_pid=$systemctl_pid" >&2
		echo ${shell_pid} ${systemctl_pid}
		#echo "TEST:$term" > /dev/$term
	done
}

#echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
#declare -g shell_pid=""
#declare -g systemctl_pid=""
#ps -elf | grep 'systemctl' | grep -v grep | awk '{print $13}' | sort -u | while read term ; do echo "$term"; lsof /dev/$term ; echo "TEST:$term" > /dev/$term ; done
process_and_parent=`find_systemctl_pids`

if has_parent_process ${process_and_parent}
then
	shell_process=$(echo ${process_and_parent} | awk '{print $1}')
	parent_term=`readlink /proc/${shell_process}/fd/2`
fi

#echo "Parent terminal: ${parent_term}"
#echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"


printf "#######################\n\r" >&2
printf "# IMPORTANT WARNING ! #\n\r" >&2
printf "#######################\n\r" >&2