0

Some of my files are separated into different directories such as /apps, /games, /docs etc.... Within each directory, is a subdirectory called _CHECKSUM. Inside this directory, is a file called openssl.sh.

For example:

openssl sha1 /path/to/apps/*.iso | sed 's/\/.*.\///' > /path/to/apps/_CHECKSUM/sum.sha1

This outputs to a file called sum.sha1 within the _CHECKSUM directory, of which the contents could look like this:

SHA1(anApp.iso)= b398c8b175411e6174942d7b4acbc5c90473a852
SHA1(anotherApp.iso)= cc150483feed3d4b607749f31eddccefd0ba5478
SHA1(yetAnotherApp.iso)= d9682a2eca25b70dddf7a906374c27ee35614c7d

However, some directories contain multiple filetypes, so the script would have to look like this:

openssl sha1 /path/to/games/*.{7z,iso} | sed 's/\/.*.\///' > /path/to/games/_CHECKSUM/sum.sha1

producing something like this:

SHA1(myFaveGame.7z)= b398c8b175411e6174942d7b4acbc5c90473a852
SHA1(anotherGoodGame.iso)= cc150483feed3d4b607749f31eddccefd0ba5478

I don't want to always run these scripts manually, so I created the following script, /path/to/scripts/openssl_recursive.sh:

#!/bin/bash
# finds every openssl.sh recursively and executes it.
IFS=$'\n'
for file in $(find /path/to -name "openssl.sh" | sort -n)
do
  echo "executing $file ..."
  sh $file
  echo "done.";
done

This seems to work fine for all directories where just one file type exists. However, for the openssl.sh scripts that contain multiple extensions, an empty sum.sha1 file is created.

Why is it that if I run the openssl.sh directly, it will create the correct result in sum.sha1 for directories with multiple filetypes, yet if I run the openssl_recursive.sh, this results in an empty sum.sha1?

jimjamz
  • 59
  • 6
  • maybe because he dnt know the path.Maybe you need to cd to that directory etc – CGeorgian Nov 06 '16 at 20:52
  • can you try 1) running it as `/bin/bash $file` and 2) workaround: `openssl sha1 /path/to/games/*.7z /path/to/games/*.iso` – Jean-François Fabre Nov 06 '16 at 20:57
  • Why are you calling `sh $file` instead of making it executable and put a `#!/bin/bash` at the top and invoke `$file` – Stefan Hegny Nov 06 '16 at 22:27
  • Pleas post the output of `bash -x ./openssl_recursive.sh`. Also see [How to debug a bash script?](http://unix.stackexchange.com/q/155551), [How to debug a bash script?](http://stackoverflow.com/q/951336/608639), [Looping through files with spaces in the names?](http://unix.stackexchange.com/q/9496), [How to list filenames that contain spaces and special characters without using find](http://unix.stackexchange.com/q/232058), [Iterate over list of files with spaces](http://stackoverflow.com/q/7039130), etc. All of them tell how to iterate over the files, and how to further process them. – jww Nov 07 '16 at 03:57
  • The output of `bash -x ./openssl_recursive.sh` is as follows: + IFS=' ' ++ sort -n ++ find /path/to/games -name openssl.sh + for file in '$(find /path/to/games -name "openssl.sh" | sort -n)' + echo 'executing /path/to/games/_CHECKSUM/openssl.sh ...' executing /path/to/games/_CHECKSUM/openssl.sh ... + sh /path/to/games/_CHECKSUM/openssl.sh /path/to/games/*.{7z,iso}: No such file or directory + echo ' done.' done. – jimjamz Nov 07 '16 at 16:45
  • @Jean-FrançoisFabre - Yes, the `/bin/bash $file` replacement worked. This recursively created a complete _sum.sha1_ file in each sub-directory, even if the directory had multiple filetypes. I'm still a newcomer to Linux and shell scripting. Please can you tell me the difference between using `sh` and `/bin/bash` and why I should not use `sh` in this instance. Thank you in advance. – jimjamz Nov 07 '16 at 21:15

1 Answers1

0

as stated here, modern Debian and Ubuntu systems symlink sh to dash by default, which is a lighter version and lacks some advanced features.

So this may not be the same shell, and probably doesn't like "rich" wildcard constructs like *.{7z,iso}. You must have fallen into that category.

On the other hand, bash accepts those wildcards happily.

So a working solution is forcing the use of /bin/bash env variable:

#!/bin/bash
# finds every openssl.sh recursively and executes it.
IFS=$'\n'
for file in $(find /path/to -name "openssl.sh" | sort -n)
do
  echo "executing $file ..."
  /bin/bash $file
  echo "done.";
done
Community
  • 1
  • 1
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • I am indeed using a Debian system and this was very informative. I went ahead and used your `/bin/bash` example and this worked, but I will also experiment with `$SHELL` as this seems to be a more robust option. Thank you! – jimjamz Nov 08 '16 at 15:20
  • When using `$SHELL $file`, as used in the above example, it still results in empty sum.sha1 files. I reverted back to using `/bin/bash $file`, which works. – jimjamz Nov 20 '16 at 10:27