Search code examples
bashsedechotailpiping

Piping echo, tail and sed leads to wrong output


I want to add an entry in fstab and I'm using this command in my /bin/bash script:

echo -n | tail -1 /mnt/etc/fstab | sed 's/\(-\).*/-03/' >> /mnt/etc/fstab
echo -e -n "\t" >> /mnt/etc/fstab  
echo -n "/home" >> /mnt/etc/fstab
echo -e -n "\t" >> /mnt/etc/fstab  
echo -n "ext4" >> /mnt/etc/fstab
echo -e -n "\t" >> /mnt/etc/fstab  
echo -n "default,noatime" >> /mnt/etc/fstab 
echo -e -n "\t" >> /mnt/etc/fstab  
echo -n "0" >> /mnt/etc/fstab 
echo -e -n "\t" >> /mnt/etc/fstab  
echo "2" >> /mnt/etc/fstab 

this is the original content:

proc                  /proc           proc    defaults          0       0
PARTUUID=ee397c53-01  /boot           vfat    defaults          0       2
PARTUUID=ee397c53-02  /               ext4    defaults,noatime  0       1

and this is the expected output:

proc                  /proc           proc    defaults          0       0
PARTUUID=ee397c53-01  /boot           vfat    defaults          0       2
PARTUUID=ee397c53-02  /               ext4    defaults,noatime  0       1
PARTUUID=ee397c53-03  /home           ext4    defaults,noatime  0       2

instead the output is the following:

proc                  /proc           proc    defaults          0       0
PARTUUID=ee397c53-01  /boot           vfat    defaults          0       2
PARTUUID=ee397c53-02  /               ext4    defaults,noatime  0       1
PARTUUID=ee397c53-03
    /home   ext4    default,noatime 0   2

What's wrong in the piping?


Solution

  • Your first line is off. You are piping echo -n to tail. echo -n produces no output so you are piping nothing to tail.

    You could append the output of your tail | sed command using echo -n instead:

    echo -n $(tail -1 /mnt/etc/fstab | sed 's/\(-\).*/-03/') >> /mnt/etc/fstab
    

    Wrapping the tail | sed bit into $() allows echo to take the stdout of those commands and echo out the results (without the line feed as desired) back into fstab.

    Alternatively you could use xargs to pipe TO echo so it can read from stdin.

    tail -1 /mnt/etc/fstab | sed 's/\(-\).*/-03/' | xargs echo -n >> /mnt/etc/fstab
    

    Also, you could use printf to do the whole script:

    printf "%s\t%s\t%s\t%s\t%s\t%s\n", $(tail -1 /etc/fstab | sed 's/\(-\).*/-03/') "/home" "ext4" "default,noatime" "0" "2"