Jelphy
Jelphy

Reputation: 1059

Check if file has been modified

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

Upvotes: 0

Views: 1632

Answers (4)

Louis Papaloizou
Louis Papaloizou

Reputation: 282

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.

Upvotes: 0

ArturFH
ArturFH

Reputation: 1787

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.

Upvotes: 1

William Pursell
William Pursell

Reputation: 212238

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 }'

Upvotes: 1

Dorian
Dorian

Reputation: 761

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.

Upvotes: 1

Related Questions