0

I am having trouble writing a bash script that saves each line of the output from the command #mount | grep ^\/dev/ into a variable.

Below is my bash script.

#!/bin/bash
mount | grep ^\/dev/ > tempoary
input=$(cat tempoary)
x=0
while IFS= read -r line
do
  x=$((x+1))
  echo "$line" > /tmp/directory/$x
  for file in $(echo "$line"); do
  eval "var$x=$file";
  echo "$file"
  done
done <<< "$input"

Output below:

[root@localhost tmp]# sh script
/dev/mapper/rhel-root
on
/
type
xfs
(rw,relatime,seclabel,attr2,inode64,noquota)
/dev/sda1
on
/boot
type
xfs
(rw,relatime,seclabel,attr2,inode64,noquota)

I expect to have output format like this:

[root@localhost tmp]# sh script
/dev/mapper/rhel-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

Can you give me some pointers to how I can achieve this?

PS. Double quoting "$(echo "$line")" won't help, it would only prompt syntax error below.

[root@localhost tmp]# sh script
script: eval: line 14: syntax error near unexpected token `('
script: eval: line 14: `var1=/dev/mapper/rhel-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)'
2
  • Clearly mount | grep ^\/dev/ will give the sort of output you want. So all this processing is for some other reason. What is it you're trying to do? After all, mount | grep ^\/dev/ | while read -r line; do echo "$line"; done is a simple loop that displays the same thing. Commented Jul 6, 2020 at 2:46
  • I am trying to save the outputs of the "mount | grep ^\/dev/" into variables within shell script, that can be used to further process if it includes certain string within the variable. So for example, the outputs are "/dev/mapper/rhel-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)" and "/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,noquota)" respectively. After saving these 2 lines into variable1 and variable2 in the bash, I would like to further process using if-then-else statement to process if they include string "noexec" within brackets, which is no. Commented Jul 6, 2020 at 7:59

3 Answers 3

1

Redirect the file directly to while ... done:

mount | grep ^\/dev/ > tempoary
while IFS= read -r line
do
...
done < temporary

or use process substiution to omit the temporary file:

while IFS= read -r line
do
...
done < <(mount | grep ^\/dev/)

or similarly pipe to while

mount | grep ^\/dev/ |
while IFS= read -r line
do
...
done
3
  • why not mount | grep ^\/dev/ | while IFS= read -r line ? Commented Jul 6, 2020 at 8:01
  • sure, that works, I just prefer done < <(cmd) for readability and habit, but it's simply a matter of choice :-) Commented Jul 6, 2020 at 8:03
  • if instructions within do .. done span too many lines, I feel loop harder to read as I don't know what is fed to loop, if command or file is before I find it easier. Commented Jul 6, 2020 at 8:05
0

Adding IFS before for loop and quoting the file variable make things working all fine... Check this out:

#!/bin/bash
mount | grep ^\/dev/ > tempoary
input=$(cat tempoary)
x=0
while IFS= read -r line
do
  x=$((x+1))
  echo "$line" > /tmp/tmp/$x
  IFS=
  for file in $(echo "$line"); do
  eval "var$x='$file'";
  echo "$file"
  done
done <<< "$input"
0

Based on the comment

the outputs are "/dev/mapper/rhel-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)" and "/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,noquota)" respectively. After saving these 2 lines into variable1 and variable2

Standard variables aren't necessarily the best answer. Instead an array is more likely to be what you want.

For example:

#!/bin/bash

typeset -A mounts

let index=0

m=$(mount | grep "^/dev/")

while read line
do
  mounts[$index]="$line"
  let index=index+1
done <<< "$m"

echo There were $index lines
let a=0
while [ $a -lt $index ]
do
  echo Line $a was ${mounts[$a]}
  let a=a+1
done

On my machine, if I run this I get

There were 4 lines
Line 0 was /dev/vda3 on / type ext4 (rw,relatime,data=ordered)
Line 1 was /dev/vda1 on /boot type ext4 (rw,relatime,data=ordered)
Line 2 was /dev/vdb on /news type ext3 (rw,relatime,data=ordered)
Line 3 was /dev/vdc1 on /brick type ext3 (rw,relatime,data=ordered)

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.