Could last pid variable $! be wrong when using yad?

436 views Asked by At

I'm trying to close a yad window from within bash script using kill command, but pids do allways mismatch. Same on command line.

$ yad & pid_01=$!
$ kill $pid_01
bash: kill: (31879) - Kein passender Prozess gefunden
$ echo $(pidof yad)
31880
$ echo $!
31879

No other yad processes running.

  1. What's going on here? Why is this pid allways wrong? (so the window fails to get closed)
  2. How can I find reliably the pid of a specific yad window when more than one yad process is running? Or is there another way to close this yad window from within a bash script? Since “kill $(pidof yad)” will probably randomly close another yad window.

I'm confused a little since I didn't notice before other programs to have this issue.

Any help appreciated.


GNU bash, Version 5.0.3(1)-release (i686-pc-linux-gnu) yad --version 0.40.0 (GTK+ 3.24.5)

1

There are 1 answers

0
MI605 On

1.) Simple answer: No, the pid itself is correct, but doesn't match the yad process running the window. There are two pids for yad always since yad obviously is called by some wrapper script rather than direcly when entering “yad” from command line or from within a script. This may be distro specific.

$ yad -- info & echo $!
29523

$ pidof yad
29524

$ ps x | grep 'yad' | grep -v 'grep'
29523 pts/0    S      0:00 /bin/bash /usr/local/bin/yad -- info
29524 pts/0    S      0:00 /usr/bin/yad -- info

Verification:

$ cat /usr/local/bin/yad
#!/bin/bash

/usr/bin/yad "$@" 2>/dev/null

so option -x will show both pids.

$ pidof -x yad
29524 29523

This doesn't help out when dealing with more than one instance of yad present (e.g. user calls script more than once); some identical pairs of yad processes are present in ps:

$ yad -- info
$ yad
$ yad -- info

$ ps x | grep 'yad' | grep -v 'grep'
22928 pts/0    S      0:00 /bin/bash /usr/local/bin/yad -- info
22929 pts/0    S      0:00 /usr/bin/yad -- info
23131 pts/0    S      0:00 /bin/bash /usr/local/bin/yad
23132 pts/0    S      0:00 /usr/bin/yad
24633 pts/0    S      0:00 /bin/bash /usr/local/bin/yad -- info
24634 pts/0    S      0:00 /usr/bin/yad -- info

2.) My solution to find reliably both pids of the specifc yad window, derived from the analysis above is:

# get yad pid of specific yad window
yad_pid_before="$(pidof -x yad) "
yad --info & \
sleep 1
yad_pid="$(pidof -x yad)"
if [ "$yad_pid_before" != " " ]; then
    while read -d' ' item
    do
        yad_pid="$(echo "$yad_pid" | sed "s/$item//g")"
    done <<<"$yad_pid_before"
fi

#testing
echo -e "yad recent window pids:\t$yad_pid\nsleeping 6s before closing."
sleep 6
kill $yad_pid

Problem description:

Yad is started using a wrapper script in at least some distros. So “kill $!” will fail. Alternative “ps x” doesn't provide sufficient information to distinguish between multiple yad windows called with identical options.

Explanation of solution:

The pids of all existing yad processes are stored in “$yad_pid_before”, immediately before new yad window is executed. The blank suffix character is intentionally and needed in order to find the last item in string. Option -x for getting script pids is mandatory.

The second (significant) pid is not immediately present, and will fail to get registered early, so “sleep 1” to wait for it.

Storing all yad pids present in “$yad_pid” after new yad window is started.

Removing any pid wich lives in “$yad_pid_before” from “yad_pid” while looping through list from here-string.

Loop is needed and to be executed merely when at least one item in “$yad_pid_before” exists, otherwise sed command will fail. Conditional branch takes care of this.

The resulting variable “$yad_pid” contains both recent pids and can now be used for kill command within script to close the specific yad window opened on second line. No other yad windows neither opened before or nor after are affected.

Works at least on bash and yad version specified in original question.

If somebody can provide a more elegant solution for this, please explain.