#! /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"
Estou procurando um programa que use um nome de arquivo (por exemplo, como um argumento), leia stdin
em um buffer e compare isso com o conteúdo do arquivo nomeado.
Se o conteúdo for diferente, o programa (idealmente atomicamente) substitui o arquivo pelo conteúdo do buffer de entrada.
Caso contrário, deixa o arquivo inalterado - nenhuma gravação ocorre, nenhuma alteração do registro de data e hora da última modificação e sem gerar um arquivo temporário.
Exemplo de uso: echo "test" | myprogram myfile.txt
Esse programa existe como uma ferramenta comum de linha de comando do Unix? Existe alguma maneira legal de conseguir isso sucintamente no shell sem um arquivo temporário? (rsync não)
#! /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"
Tanto quanto sei, não existe uma ferramenta existente que faça o que você deseja.
O script a seguir myprogram
deve funcionar:
#!/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