find | xargs shasum creates checksum of checksum file itself (prematurely) and fails when checking

user121391

My problem (in a script with #!/bin/sh) is as follows: I try to checksum all files in a directory for archival purposes. The checksum (in my case sha1) file with all filenames should reside in the same directory. Lets say we have a directory ~/test with files f1 and f2: .

mkdir ~/test
cd ~/test
echo "hello" > f1
echo "world" > f2

Now calculating the checksums with

find -maxdepth 1 -type f -printf '%P\n' | xargs shasum

does exactly what I want, it lists all files of the current directory only and calculates the sha1 sums (maxdepth may be changed later). The output on STDOUT is:

f572d396fae9206628714fb2ce00f72e94f2258f  f1
9591818c07e900db7e1e0bc4b884c945e6a61b24  f2

Unfortunately, when trying to save this to a file with

find -maxdepth 1 -type f -printf '%P\n' | xargs shasum > sums.sha1

the resulting file displays the checksum for itself:

da39a3ee5e6b4b0d3255bfef95601890afd80709  sums.sha1
f572d396fae9206628714fb2ce00f72e94f2258f  f1
9591818c07e900db7e1e0bc4b884c945e6a61b24  f2  

and therefore fails at a later shasum --check, because of the obvious problem of additional file modification when saving the last sum.

I looked around and by using -p flag for xargs, I found out that it somehow creates the output file before even executing the find command, therefore the additional file is found and will be checksummed...

I know that as a workaround I could save the checksum to another location (temp directory via mktemp) or exclude it in find specifically, but I'd like to understand why it behaves the way it does - which is in my eyes not that useful, for example if the first command would check if the output file is already on disk, it would never get the correct answer...

Anthon

You can prevent the file from reaching xargs using:

find . -maxdepth 1 -type f ! -name sums.sha1 -printf '%P\n' |
  xargs -r shasum -- > sums.sha1

To prevent problems with filename that have blanks or newlines or quotes or backslashes, I would however use:

find . -maxdepth 1 -type f ! -name sums.sha1 -printf '%P\0' |
  xargs -r0 shasum -- > sums.sha1

instead.

The -- is to avoid problems with file names that start with -. It will however not help for a file called -. Had you used -print0 instead of -printf '%P\0', you wouldn't have needed the -- and would not have had a problem with the - file.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

TOP Ranking

HotTag

Archive