Use sed command to check if a particular line exists, if not, add it
Solution 1
We note down the pts/ number when we meet the corresponding line. The -p
option will autoprint
lines. When we reach the eof
we pull out the hash %h
to and pass it thru the grep
filter to determine which terminals didn't print and we use map
to prepare the format for that to happen.
perl -lpe 'm|^pts/([0-9])$| and $h{$1}++;
END{ print for map { "pts/$_" } grep { !$h{$_} } 0 .. 9; }
' /etc/securetty
We initialize the hold space
with numbers 0 1 2 ... 9. Whenever we meet the pts/[0-9]
line, we clip this from the hold space. At eof
, we get hold of hold space and if any numbers are found shall the massaged to the proper format and printed out.
sed -e '
# initialize the hold space with 0 1 ... 9
1{x;s|.*|'"$(echo {0..9})"'|;x}
# whatever be the line, it needs to be printed
p
# we meet a valid pts/ line
\|^pts/[0-9]$|{
# the hold space gets appended to the pattern space
G
# grab what is the pts number and search for it in the hold and
# delete itand store back the changes into hold space.
s|^pts/\([0-9]\)\n\(.*\)\1 |\2|;h
}
# weve not arrived at the eof and weve processed the input so go no further
$!d
# we are at the eof, so we bring back the hold space. just in case all
# numbers were dealt with up, we simply bail out. Else, prepend the str
# pts/ to the numbers present and simply were home
g;/[0-9]/!d;s/ //g
s|[0-9]|pts/&\n|g;s/.$//
# *TIP*: Sprinkle the l, list pattern space at various places to see
# whats going on.
' /etc/securetty
Solution 2
Remove any/all pts/N
lines, then add them all back in:
{ grep -xv '^pts/[0-9]$' /etc/securetty; printf 'pts/%d\n' {0..9}; } > /etc/securetty.new
cat /etc/securetty.new
mv /etc/securetty.new /etc/securetty
You could also do this in one go with your favorite text processing tool e.g. ed
ed -s /etc/securetty <<IN
g/^pts\/[0-9]$/d
.r ! printf pts/\%d\\\n {0..9}
,p
q
IN
(replace ,p
with w
to edit in-place) or sed
{ printf '%s\\\n' '$a' pts/{0..8}
printf '%s\n' 'pts/9' '/^pts\/[0-9]$/d'
} | sed -f- /etc/securetty
which is pretty much the same as plain
sed '$a\
pts/0\
pts/1\
pts/2\
pts/3\
pts/4\
pts/5\
pts/6\
pts/7\
pts/8\
pts/9
/^pts\/[0-9]$/d' /etc/securetty
(use sed
with -i
to edit the file in-place)
Solution 3
To add a single line when it's missing can be done by removing each occurence and appending it at the end:
sed -n '/pattern/!p;$a pattern'
But it's nasty to repeat that for 10 patterns.
sed '/pts\/[0-9]/d;$a pts/0 ...
will fail if the last line is to be removed. So the other way around, assuming the first line is the only one starting with #
:
sed '/#/a pts/0\
pts/1\
pts/2\
pts/3\
pts/4\
pts/5\
pts/6\
pts/7\
pts/8\
pts\9
/pts\/[0-9]/d'
Nasty. I suggest to use a different tool in this case.
Solution 4
You could search the securetty file and add missing entries as follows:
for x in 0 1 2 3 4 5 6 7 8 9
do
grep "pts/${x}" /etc/securetty || echo "pts/${x}" >> /etc/securetty
done
sort /etc/securetty -o /etc/securetty
Related videos on Youtube
skrowten_hermit
Updated on September 18, 2022Comments
-
skrowten_hermit over 1 year
I want to add more terminals to the file
/etc/securetty
. More specifically I would like to addpts/n
, wheren
is in the range0-9
, if it does not exist. Is this possible throughsed
command? The following is how the contents of my/etc/securetty
are:# Local X displays (allows empty passwords with pam_unix's nullok_secure) pts/0 pts/1 pts/2 pts/3
I tried some thing like:
sudo sed '+pts/3+a pts/4' /etc/securetty
which gives the following error:
sed: -e expression #1, char 3: extra characters after command
-
choroba about 7 yearsDo you want to add the first missing
pts/n
, or all of them? -
skrowten_hermit about 7 yearsAdd if any are missing and all if none are present.
-
Philippos about 7 yearsUsing a different delimiter than
/
works fors
command, but not for addressing, so it would be '/pts\/3/a pts/4' -
tripleee about 7 yearsYou can use a different delimiter when matching, too, but you need to escape it.
'\+pts/3+a pts/4'
-
Jeff Schaller about 7 yearsIf any of the existing answers solves your problem, please consider accepting it via the checkmark. Thank you!
-
-
choroba about 7 yearsThe script only adds missing lines, it doesn't remove anything. The argument is the name of the file (
/etc/securetty
). Don't run the script if you don't understand how it works! -
skrowten_hermit about 7 yearsBut my file contains other terminal names as well. Say,
ttyUSB0
etc. They would still remain right? I was assumingsed
should have some way to get around this. Saw examples usingsed
where you could change lines. -
skrowten_hermit about 7 yearsI'm looking for something like this, but would like to understand what this does. Could you add comments/explanation line by line what's going on? And the
perl
command is for? -
Philippos about 7 yearsThe
sed
solution is a beautiful hack. Nothing I would do in real life, but surely a brilliant puzzle! +1 -
skrowten_hermit about 7 yearsI like this idea, though it's a bit nasty (more
sed
commands can be piped right?). Butsed '/pts\/[0-9]/d;$a pts/0' /etc/securetty
appendedpts/0
to the end of the file. I would like to insert in place. Any way to do this by modifying/tweaking a bit? -
Philippos about 7 years@skrowten_hermit: Sharma's
sed
solution does leave the lines where they are and only append the missing ones at the end. You could even use the-i
option to edit in place, if yoursed
version supports it. -
Admin about 7 years@Philippos I would like to give this solution very inventive. But somehow I am not able to give any marks to anything on this site. I would advise @ skrowten to go with this as it is short/swift/less noise.
-
skrowten_hermit about 7 years@Philippos, Nope. Tried
-i
option. It still appends to the bottom of the file. I wanted to insert below the line# Local X displays (allows empty passwords with pam_unix's nullok_secure)
after the lines are removed. -
skrowten_hermit about 7 yearsI entered the following
sed -e '1{x;s|.*|'"$(echo {0..9})"'|;x}p\|^pts/[0-9]$|{s|^pts/\([0-9]\)\n\(.*\)\1 |\2|;h}$!dg;/[0-9]/!d;s///gs|[0-9]|pts/&\n|g;s/.$//' /etc/securetty
and the following error is thrown:sed: bad option in substitution expression
-
skrowten_hermit about 7 yearsThough this does add the lines, and is an alternative to
sed
, it doesn't really add the missing entries. Moreover, it doesn't add in-place but append to the end of the file. -
Jeff Schaller about 7 yearsIs it possible you missed the trailing
'
for thesed
statement? -
L.Ray about 7 yearsIt certainly does add the missing lines to the /etc/securetty file (don't be fooled by the output to your screen). I added a line to address your sort concerns.