Andrew
Andrew

Reputation: 239097

How to display a diff of two files in a Bash script?

I'm trying to compare the contents of two files in a bash script.

local_file=$(cat my_local_file.txt)
remote_file=$(curl -s "http://example.com/remote-file.txt")

if [ local_file == remote_file ]; then
  echo "Files are the same"
else
  echo "Files are different. Here is the diff:"
  diff <(echo "$local_file") <(echo "$remote_file")
fi

When I run the script, I see that I have a syntax error:

./bin/check_files.sh: line 8: syntax error near unexpected token `('
./bin/check_files.sh: line 8: `  diff <(echo "$local_file") <(echo "$remote_file")'

What am I doing wrong? How can I display a diff of these two strings from a bash script?

Upvotes: 1

Views: 3798

Answers (3)

codeforester
codeforester

Reputation: 43089

In addition to the <(command) (process substitution) syntax issue, your code if [ local_file == remote_file ] compares the literal strings local_file and remote_file, rather than the content of the variables. You need $local_file and $remote_file to compare the contents. Need to enclose them in double quotes to prevent word splitting issues.

You could do this:

#!/bin/bash

local_file=$(< my_local_file.txt) # this is more efficient than $(cat file)
remote_file=$(curl -s "http://example.com/remote-file.txt")

if [ "$local_file" = "$remote_file" ]; then
  echo "Files are the same"
else
  echo "Files are different. Here is the diff:"
  diff <(printf '%s' "$local_file") <(printf '%s' "$remote_file")
fi

As stated by @dimo414, the limitation here is that the command substitution $(...) removes trailing newlines and that would cause a problem. So, it is better to download the remote file and compare it with the local file:

local_file=my_local_file.txt
curl -s "http://example.com/remote-file.txt" -o remote_file

if diff=$(diff -- "$local_file" remote_file); then
  echo "Files are the same"
else
  echo "Files are different. Here is the diff:"
  printf '%s' "$diff"
fi

Upvotes: 2

hek2mgl
hek2mgl

Reputation: 158250

Process substitution is a bash feature, which is usually not available in /bin/sh which is meant to be POSIX compatible.

Make sure to use the following shebang line if you want to run the script as an executable:

#!/bin/bash

instead of

#!/bin/sh

or use

bash script.sh

instead of

sh script.sh

if you run it like that


To make the script work with POSIX conform shells I would just download the file and compare it against the local file. Remove the downloaded file after the diff.

Upvotes: 5

latika bhurani
latika bhurani

Reputation: 80

You can also use the following command:

cmp -b "File_1.txt" "File_2.txt"

Upvotes: -1

Related Questions