0

I am new to scripts, and I want to monitor top 2 process with high memory usage, and keep lists of processes that are not mysqld.

I wrote a script below,

lines=$(ps aux --sort rss | head -n 3)
echo $lines
for line in $lines
do
    echo $line
done

and found out that it prints words instead of lines.

How can I save a line in the variable line?

  • There are two types of arrays in bash: _indexed_ arrays and _associative_ arrays. Your variable `lines` only holds a single string (scalar), holding the first three lines from the `ps` output. – user1934428 Apr 05 '22 at 09:25

1 Answers1

1

You are not creating an array at all. The syntax for that would look like

lines=($(ps aux --sort rss | head -n 3))

where the inner $(...) is a command substitution which simply expands to a sequence of tokens (not lines!) and the outer parentheses declare an array.

Probably a much better solution entirely is to just loop over the output from ps directly. Collecting the results in an array is only useful if you need to traverse the values repeatedly for some reason (like sort them by different criteria, or loop over them multiple times).

ps aux --sort rss | head -n 3

or if you want to decorate the output further, perhaps

ps aux --sort rss | head -n 3 |
while IFS= read -r line; do
    echo "the output was $line with proper quoting"
done

(though with a static decoration around the value, maybe simply prefer ps aux --sort rss | head -n 3 | sed 's/.*/the output was & with some decorations/').

With recent versions of Bash, you can read the values into an array with readarray -t.

readarray -t lines < <(ps aux --sort rss | head -n 3)
for line in "${lines[@]}"; do  # notice proper array syntax
   echo "$line"                # notice proper quoting
done

The array syntax is slightly odd, but needs to be backwards-compatible with the original Bourne shell, where $lines will always refer to a single string value.

(readarray is Bash v4+ so not available e.g. on MacOS out of the box currently.)

tripleee
  • 158,107
  • 27
  • 234
  • 292