2

I am looking for a program that takes a file name (e.g. as an argument), reads from stdin into a buffer, and compares this with the contents of the named file.

If the contents differ, the program (ideally atomically) overwrites the file with the contents of the input buffer.

Otherwise, it leaves the file unchanged - no write occurs, no change of last-modified timestamp, and without generating a temporary file.

Example Usage: echo "test" | myprogram myfile.txt

Does this program exist as a common Unix command line tool? Is there some nice way to achieve this tersely in the shell without a temporary file? (rsync do otherwise)

2 Answers 2

1
#! /bin/bash

TMP_FILE=/tmp/myprogram.$$.tmp
COMP_FILE="$1"

test -f "$COMP_FILE" && test -r "$COMP_FILE" && test -w "$COMP_FILE" || exit 2

cat >"$TMP_FILE"
cmp "$COMP_FILE" "$TMP_FILE" || cp "$TMP_FILE" "$COMP_FILE"
rm "$TMP_FILE"
0

As far as I know there is not an existing tool that does what you want. The following script myprogram should work:

#!/bin/bash

var="$(cat)"
md5_stdin=$(echo "$var" | md5sum | cut -d" " -f 1)
md5_file=$(md5sum myfile.txt | cut -d" " -f1)
[[ "$md5_stdin" != "$md5_file" ]] && echo "$var" > myfile.txt

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.