0

I have a process which is getting launched by two different processes(one is by init and other by lxc container)

I am trying to get the pids of the process using process name by command $(pidof $PROCESS_NAME), which works fine. The command gives 2 pid values , but when i try to print the individual values using a=(${process_pids[0]}) and b=(${process_pids[1]}) only first command yields the first value, second one prints empty.

Also the length is showing as 1 despite we have two elements in the array process_pids

On the other way if we enable numbers_normal=(1234 5678) instead of process_pids=$(pidof $PROCESS_NAME) , though echo "pids = $numbers_normal" print only one value, the indexing is working fine.

What is the problem with the statement process_pids=$(pidof $PROCESS_NAME) and how to correct it.

#!/bin/sh
PROCESS_NAME=process1
process_pids=$(pidof $PROCESS_NAME)
#numbers_normal=(1234 5678)
echo "pids = $process_pids"
a=( ${process_pids[0]} )
b=( ${process_pids[1]} )
echo "0th = $a"
echo "1st = $b"
# lengths are showing as 1, but the number of items are 2
echo "length = ${#process_pids[*]}"
echo "L = ${#process_pids[@]}"

for i in ${process_pids[@]}; do
    echo "pid $i parent is $(ps -o ppid= -p $i)"
done

1 Answer 1

3

If you're going to use arrays, use a shell with array support such as zsh, bash, ksh or yash. The sh language has no arrays (though some sh implementations do implement some array support as an extension in a variety of ways). So here, the she-bang should be #! /bin/bash -, not #!/bin/sh.

Then, you need to initialise process_pids as an array:

process_pids=($(pidof -- "$PROCESS_NAME"))

Note the extra parentheses around the process substitution. Your current assignment sets process_pids as a scalar.

By leaving the $(...) unquoted within the array=(...) declaration, we're invoking the split+glob operator (split only with zsh), and assuming $IFS has not been modified, the output of pidof will be split on the newline or space characters that pidof uses to separate pids in its output.

With this, your loop will work correctly, with quotes (as intended with [@]):

for i in "${process_pids[@]}"; do
2
  • There's also that anti-pattern of thinking one has to store intermediate results in variables. In this particular question, there is no need for any arrays. You can read from pidof (or pgrep) directly with an unquoted command substitution in a for loop (assuming $IFS is sane), or safer, in a while loop using read.
    – Kusalananda
    Oct 8, 2021 at 13:15
  • 1
    @they, or even, on Linux distributions (which the pidof command suggests the OP is using): ppids=( $(ps -o ppid= -C "$PROCESS_NAME" | sort -nu) ) Oct 8, 2021 at 13:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .