0

How can I validate that this replace command succeeded:

perl -pi -e 's/contoso/'"$hostname"'/g' /etc/inet/hosts

I have tried checking the return value:

if [ $? -eq 0 ]; then
    echo "OK"
else
    echo "Error."
fi

But the return value is not being set when the command fails.

Thanks

Jelphy
  • 961
  • 2
  • 11
  • 28
  • When the command fails, the return value is not 0. It actually is set. – zhenguoli Jun 12 '17 at 12:51
  • check https://stackoverflow.com/questions/15965073/return-code-of-sed-for-no-match – P.... Jun 12 '17 at 12:57
  • What determines success? ... and likewise for failure? Your command will modify the file regardless of whether or not it matches the string; It's unclear if that's what you are deeming successful. – l'L'l Jun 12 '17 at 13:12

4 Answers4

1

I don't know Perl, but you can manage multiple case of "error" (no match/no way to write in file) with a little Bash script like that :

#!/bin/bash

FILE="/etc/inet/hosts"
SEARCH="contoso"
REPLACE="$hostname"
NB=$(grep -c $SEARCH $FILE)

if [ $NB -ne 0 ]; then
    perl -pi -e 's/${SEARCH}/'${REPLACE}'/g' "$FILE" && echo "${NB} replaced" || echo "Error (permission maybe)"
else
    echo "No match in file"
fi

I think there is a better way by improving the Perl code or by using the sed command. But it should works.

Dorian
  • 761
  • 3
  • 11
  • 28
1

If you expect your perl script to return a value that has some meaning, you will need to write your perl script to return a meaningful value. In your case, perhaps something as simple as:

perl -p -e 's/contoso/'"$hostname"'/g; $rv=1 if $&; END{ exit !$rv }'
William Pursell
  • 204,365
  • 48
  • 270
  • 300
1

One option is to check, if file has been modified. You can achieve with adding extension of backup file to -i option:

perl -pi.orig -e 's/contoso/'"$hostname"'/g' /etc/inet/hosts

This command will store original content of /etc/inet/hosts into /etc/inet/hosts.orig. Then run the specified command. Then you can check if the files are different with, for example cmp command:

if ! cmp -s foo.txt foo.txt.orig; then
    echo OK
else
    echo ERROR
fi

Remove the .orig file after that.

The other option is to modify the script to read the content of the file, replace required entry, check is change actually happened and return proper status at the end to verify in the shell using $?. You have been given solution in this answer.

ArturFH
  • 1,697
  • 15
  • 28
0

Generally checksums is a very efficient way to detect changes in files.

md5sum [filename]

root@miaoulis:~# echo 'line 1' >>1.txt
root@miaoulis:~# md5sum 1.txt
5c2ce561e1e263695dbd267271b86fb8  1.txt
root@miaoulis:~# echo 'line 2' >>1.txt
root@miaoulis:~# md5sum 1.txt
c7253b64411b3aa485924efce6494bb5  1.txt

I guess the sum could be extracted from the output with AWK

root@miaoulis:~# echo $(md5sum 1.txt) | awk 'BEGIN{FS=" *"}{print "MD5:",$1}'
MD5: c7253b64411b3aa485924efce6494bb5

root@miaoulis:~# echo $(md5sum 1.txt) | awk 'BEGIN{FS=" *"}{print "filename:",$2}'
filename: 1.txt

FS=" *" instructs AWK to split the string on the occurrence of one or more spaces. $1 will be the MD5, $2 will be the filename.

MD5 checksum works fast for any size of file. The downside is that you don't really detect what exactly changed in the file, only the fact that it has changed. Should be good enough for most scenarios.

Louis Papaloizou
  • 284
  • 1
  • 3
  • 11