Reputation: 259
My result variable contains the following:
auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=888
auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=888
I want to replace the entire lines and I'm using sed. The replace seems to work okay fir first iteration but not second one. However, when I print the values, it shows that the new value is correctly updated.
echo "$result" |
while IFS= read -r line;
do
newValue=""
for ii in $line
do
if [[ "$ii" != *"unlock_time"* ]]; then
newValue="$newValue $ii"
fi
done
newValue="$newValue unlock_time=900"
sed -i "s/$line/$newValue/g" $password_auth
echo " Line : [ $line ]"
echo "newValue : [ $newValue ]"
done
The output shows this:
Line : [ auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=900 ]
newValue : [ auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=900 ]
Line : [ auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=888 ]
newValue : [ auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=900 ]
Here when it is displaying I see that the correct value is present in the variables and all the prints take place after sed command and I see no errors before prints in output.
But when I check the file, I see the second instance of unlock_time is still 888 instead of 900.
Note: I cannot globally replace unlock_time which is why I'm storing the lines that need updating in result.
Is there anything that is overlooked in the loop?
Update: I've tried running the sed commands on command line:
sed -i "s/auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=900/auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=999/g" temp <-- This works
sed -i "s/auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=9/auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=900/g" temp <-- This doesn't update file but doesn't throw an error either
The command works on command line when I put escape characters around [default=die]. But how do I do it if I'm doing it through script?
Upvotes: 0
Views: 322
Reputation: 16868
You are trying to find a constant. The regexp matching through layers of quoting is getting in the way. Here's a simpler perl method (wrapped in bash for demo purposes):
#!/bin/bash
result="auth required pam_faillock.so preauth silent audit deny=3 even_deny_root fail_interval=888 unlock_time=888
auth [default=die] pam_faillock.so authfail audit deny=3 even_deny_root fail_interval=888 unlock_time=888"
# create a file to play with
echo "$result" > testfile
echo "$result" | perl -i -pe '
BEGIN { @find = <STDIN> }
for $str (@find) {
s/(\bunlock_time)=\d+/$1=900/ if $_ eq $str;
}
' testfile
# check the result
cat testfile
-i
does inplace editing like sed-p
wraps a while loop to read each line so an explicit one isn't needed and prints out the line after possible modification (a bit like sed)BEGIN
section initialises the array of strings to look for (from result)$_
), for
compares it against all the strings, and if
there is a literal match (eq
), does a regexp search&replace on the unlock_time parameter Upvotes: 1