Add a kernel parameter with sed to grub - linux

I'm writing a bash script to non-interactively enable hibernation on a linux system. To this end, I need to insert a shell variable that contains slashes on a specific line of a while, inside quotes that are on that line.
The relevant part of the file to b edited looks like this:
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Manjaro"
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""
I need to change it to this:
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Manjaro"
GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=/dev/disk/by-partuuid/c5a552c2-fe8f-423a-9037-c35bf090d9c3"
GRUB_CMDLINE_LINUX=""
The added parameter is provided by a shell variable.
I tried this:
sed -i '\*^GRUB_CMDLINE_LINUX_DEFAULT* s*"$* '"$(grub_resume_boot_option)"'"*' /etc/default/grub
Logic that I was aiming for was: "Look for a line that starts with pattern "GRUB_CMDLINE_LINUX_DEFAULT", and replace the last " with the given pattern. Use * as delimiter to preserve the slashes in the expanded variable."
However, the command fails if there are any spaces at the end of the line. Is there any way to make it not take spaces at the end of the line into account?
Also, if there is more simple or readable solution to this, I would be very interested.

You can do:
sed -i 's#^\(GRUB_CMDLINE_LINUX_DEFAULT="quiet\)"$#\1 resume=/dev/disk/by-partuuid/c5a552c2-fe8f-423a-9037-c35bf090d9c3"#' /etc/default/grub
Example:
$ sed 's#^\(GRUB_CMDLINE_LINUX_DEFAULT="quiet\)"$#\1 resume=/dev/disk/by-partuuid/c5a552c2-fe8f-423a-9037-c35bf090d9c3"#' <<<'GRUB_CMDLINE_LINUX_DEFAULT="quiet"'
GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=/dev/disk/by-partuuid/c5a552c2-fe8f-423a-9037-c35bf090d9c3"

From: https://serverfault.com/questions/885684/editing-the-value-of-grub-cmdline-linux-default-thru-bash-script
sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/&newstuff /' /etc/default/grub
This will add "newstuff" to the beginning of the list of params. Examples:
sed 's/^GRUB_CMDLINE_LINUX_DEFAULT="/&newstuff /' <<< 'GRUB_CMDLINE_LINUX_DEFAULT="quiet"'
GRUB_CMDLINE_LINUX_DEFAULT="newstuff quiet"
sed 's/^GRUB_CMDLINE_LINUX_DEFAULT="/&newstuff /' <<< 'GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"'
GRUB_CMDLINE_LINUX_DEFAULT="newstuff quiet splash"

sed -i "s/GRUB_CMDLINE_LINUX_DEFAULT="[^"]*/& $(grub_resume_boot_option)/" /etc/default/grub

Related

Comments in sed command file

Can I put comments (or something functionally equivalent) into a sed command file?
subs.sed
s/this/that/g
# comment
s/it/they/g
$ sed -i -f subs.sed <(echo this it)
that they
Yes, comments can be added to a sed file using #.
From the manual page of sed:
Command Synopsis
...
#comment
The comment extends until the next newline (or the end of a -e script fragment).

How can I replace a line of text in a file with a single command when the line contains a variable?

I have a script called script.sh which has the contents
export HELLO=$WORLD
I want to change it using a single command to
export HELLO=${WORLD:2:3}
I'm attempting to use the sed command but i'm new to linux and can't quite get it right. Here's what I have
sed -i 's/export HELLO=$WORLD/export HELLO=${WORLD:2:3}' script.sh
How should this line be written to replace the text correctly?
You just missed a / at the very end:
sed -i 's/export HELLO=$WORLD/export HELLO=${WORLD:2:3}/' script.sh
^
this / is missing
The $ is a special symbol that means end of line, also as #yvesonline points out you are missing the trailing /. This is how I would do it:
sed -i 's/\(export HELLO=\$\)\(WORLD\)/\1{\2:2:3}/' script.sh

Sed how to find and replace a value using a bash variable [duplicate]

I have a configuration file (gpsd.default) containing data with the following format:
# If you must specify a non-NMEA driver, uncomment and modify the next line
GPSD_SOCKET="/var/run/gpsd.sock"
GPSD_OPTIONS=""
GPS_DEVICES=""
I am making a change on the file with sed:
sed -i 's/^GPS_DEVICES="".*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
or
sed -i '4s/^.*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
The above sed command returns error:
sed: bad option in substitution expression
Because the new line contains "/" in its expression.
How to update my sed command to make it work?
This is because you are using a regex containing /, which is the same character sed uses as delimiter.
Just change the sed delimiter to another one, for example ~:
sed -i 's~^GPS_DEVICES="".*~GPS_DEVICES="dev/ttyUSB1"~' /etc/default/gpsd.default
By the way, since you are changing files in /etc, you may want to use -i.bak, so that the original file gets backed up. It is a good practice to prevent loss of important information.
You should update your sed command to this.
sed -i 's/^GPS_DEVICES=\"\".*/GPS_DEVICES=\"dev\/ttyUSB1\"/' /etc/default/gpsd.default

Sed error : bad option in substitution expression

I have a configuration file (gpsd.default) containing data with the following format:
# If you must specify a non-NMEA driver, uncomment and modify the next line
GPSD_SOCKET="/var/run/gpsd.sock"
GPSD_OPTIONS=""
GPS_DEVICES=""
I am making a change on the file with sed:
sed -i 's/^GPS_DEVICES="".*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
or
sed -i '4s/^.*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
The above sed command returns error:
sed: bad option in substitution expression
Because the new line contains "/" in its expression.
How to update my sed command to make it work?
This is because you are using a regex containing /, which is the same character sed uses as delimiter.
Just change the sed delimiter to another one, for example ~:
sed -i 's~^GPS_DEVICES="".*~GPS_DEVICES="dev/ttyUSB1"~' /etc/default/gpsd.default
By the way, since you are changing files in /etc, you may want to use -i.bak, so that the original file gets backed up. It is a good practice to prevent loss of important information.
You should update your sed command to this.
sed -i 's/^GPS_DEVICES=\"\".*/GPS_DEVICES=\"dev\/ttyUSB1\"/' /etc/default/gpsd.default

Bash: Update a variable within a file

I know this is a simple answer and I could probably keep digging around on Google before I stroll across the answer. But I am on a tight schedule and I was hoping for an easy response.
I need to update a variable in ifcfg-eth0 upon an installation. So in other words, this is what needs to happen:
The following variables need to change from:
ONBOOT=no
BOOTPROTO=dhcp
to
ONBOOT=yes
BOOTPROTO=static
Thanks in advance!
Cheers.
sed -i -e '/^ONBOOT=/s|.*|ONBOOT=yes|; /^BOOTPROTO=/s|.*|BOOTPROTO=static|' file
Also try:
sed -i -re 's|^(ONBOOT=).*|\1yes|; s|^(BOOTPROTO=).*|\1static|' file
Or
sed -i -e 's|^\(ONBOOT=\).*|\1yes|; s|^\(BOOTPROTO=\).*|\1static|' file
You can make use of something like this, which lets you define exactly what values you want to add in the file:
$ bootproto="static"
$ sed -r "s/(BOOTPROTO\s*=\s*).*/\1$bootproto/" file
ONBOOT=no
BOOTPROTO=static
And to make the two of them together:
$ onboot="yes"
$ bootproto="static"
$ sed -r -e "s/(ONBOOT\s*=\s*).*/\1$onboot/" -e "s/(BOOTPROTO\s*=\s*).*/\1$bootproto/" file
ONBOOT=yes
BOOTPROTO=static
Explanation
(BOOTPROTO\s*=\s*).* catches a group of text containing BOOTPROTO + any_number_of_spaces + = + any_number_of_spaces. Then, matches the rest of the text, that we want to remove. \1$var prints it back together with the given variable.
\s* keeps the current spaces as they were and then replaces the same line changing the current text with the bash variable $bootproto.
-r is used to catch groups with () instead of \( and \).
To make it edit in place, use sed -i.bak. This will create a backup of the file, file.bak, and the file will be updated with the new content.
All together:
sed -ir -e "s/(ONBOOT\s*=\s*).*/\1$onboot/" -e "s/(BOOTPROTO\s*=\s*).*/\1$bootproto/" file
The similar as the sed solutons with perl
perl -i.bak -pe 's/(ONBOOT)=no/$1=yes/;s/(BOOTPROTO)=dhcp/$1=static/' files....

Resources