Reputation: 3426
I have some pseduocode below and would like to know if it would work/ is the best method to tackle the problem before I begin developing the code.
I need to dynamically search through a directory on one server and find out if it exists on another server or not. The path will be different so I use basename and save it as a temporary variable.
for $FILE in $CURRENT_DIRECTORY
$TEMP=$(basename "$FILE" )
if [ssh user@other_serverip find . -name '$TEMP']; then
//write code here
fi
Would this if
statement return true if the file existed on the other server?
Upvotes: 0
Views: 42
Reputation: 16128
Here is a functioning, cleaner implementation of your logic:
for FILE in *; do
if ssh user@other_serverip test -e "$FILE"; then
# write code here
fi
done
(There won't be a path on files when the code is composed this way, so you don't need basename
.) test -e "$FILE"
will silently exit 0 (true) if the file exists and 1 (false) if the file does not, though ssh
will also exit with a false code if the connection fails.
However, that is a very expensive way to solve your issue. It will fail if your current directory has too many files in it and it runs ssh
once per file.
You're better off getting a list of the remote files first and then checking against it:
#!/bin/sh
if [ "$1" != "--xargs" ]; then # this is an internal flag
(
ssh user@other_serverip find . -maxdepth 1 # remote file list
find . -maxdepth 1 # local file list
) |awk '++seen[$0]==2' |xargs -d "\n" sh "$0" --xargs # keep duplicates
else
shift # remove the --xargs marker
for FILE in "$@"; do
# write code here using "$FILE" (with quotes)
done
fi
This does two things. First, since the internal --xargs
is not given when you run the script, it connects to the remote server and gets a list of all files in the home directory there. These will be listed as ./.bashrc
for example. Then the same list is generated locally, and the results are passed to awk
.
The awk
command builds an associative array (a hash) from each item it sees, incrementing it and then checking the total against the number two. It prints the second instance of any line it sees. Those are then passed on to xargs
, which is instructed to use \n
(a line break) as its delimiter rather than any space character.
Note: this code will break if you have any files that have a line break in their name. Don't do that.
xargs
then recursively calls this script, resulting in the else
clause and we loop through each file. If you have too many files, be aware that there may be more than one instance of this script (see man xargs
).
This code requires GNU xargs
. If you're on BSD or some other system that doesn't support xargs -d "\n"
, you can use perl -pe 's/\n/\0/' |xargs -0
instead.
Upvotes: 2
Reputation: 11940
It would return true if ssh
exits successfully.
Have you tried command substitution and parsing find
's output instead?
Upvotes: 1