I think what you really want here is rsync
:
rsync --list-only --files-from="$2" "$1" "$1/.."
The last argument is a dummy argument but is necessary; it could be any directory so long as it's not the same directory as $1
itself.
Alternatively, if all you want is the exit status and less verbosity:
rsync --dry-run --files-from="$2" "$1" "$1/.."
(Optionally add 2>/dev/null
on the end, if you really only want the exit status.)
Now, for a review of the broken script you posted:
for file in `cat ${2}` #$2 is file.txt
Backticks are deprecated; see Have backticks (i.e. cmd
) in *sh shells been deprecated?
You're assuming that the filename passed in $2
doesn't have any spaces or special characters in its name; see Why does my shell script choke on whitespace or other special characters?
You're also assuming that all files listed in $2
don't have any special characters or whitespace in their names.
And you're assuming that the list is short enough that it won't exceed your shell's maximum length for an argument list. If the list contains wildcards (e.g. /*/*/*/*/../../../../*/*/*/*
) then you will have lots and lots of problems.
do
if [ ! -f "${1}/${file}" ]; # $1 is a path
Do you really only want regular files to be allowed? And not special files of any kind, and not even directories? If so then you may need to revise the rsync
command given earlier.
Also, stylistic point: putting the !
before the [
as in if ! [ -f "$1/$file" ]
is less likely to lead you astray. Nothing wrong with it in this specific case, however. (If you combine [ ! ... ]
with missing double quotes you are very likely to be led astray.)
then
echo "$file is missing"
notok=$?
Unless the echo
command fails, you're setting notok
to 0 here in every case.
This is even sillier when you realize that you've already checked the exit status. You don't need to do so again. If you wrote notok=1
here (and added notok=0
to the top of your script) you would get a simpler and better form.
fi
done
if [ ${notok} -eq 0 ];
Missing double quote characters. Again, see Why does my shell script choke on whitespace or other special characters? (and note its subtitle "an introductory guide to robust filename handling and other string passing in shell scripts").
then
echo "need to check"
This message makes absolutely no sense. Need to check what? Who needs to check what? Huh?
exit 1
else
echo "All files present"
fi
The rest is fine. Ish.
Replacement script
if rsync --dry-run --files-from="$2" "$1" "$1/.." 2>/dev/null; then
echo "All files present"
else
echo "need to check"
exit 1
fi
Replacement script that disallows directories in list (will throw an error on them)
if ! rsync --dry-run --files-from="$2" "$1" "$1/.." --no-dirs 2>&1 | grep -q .; then
echo "All files present"
else
echo "need to check"
exit 1
fi
${x}
expands to nothing. Is that all your code? – nxnev Dec 13 '17 at 06:12-eq: unary operator expected
is a direct result ofx
being unset or empty. – Travis Clarke Dec 13 '17 at 06:31notok
can be unset in some cases, so IMO this just falls back to the lack of quoting – ilkkachu Dec 13 '17 at 10:29notok
is unset in some cases, making-eq
the first argument. – Toby Speight Dec 13 '17 at 11:23