The immediate problem is that the function you declare is not visible to the second bash
instance you run from find ... -exec
. https://shellcheck.net/ probably just sees a single-quoted literal string, and does not look inside it for problems.
Using sh
to run a Bash script could also be a problem. Your script doesn't use any Bash features other than the nonstandard function
declaration, but there is really no reason to prefer that over the standard POSIX function declaration syntax. (If sh
is a symlink to Bash on your system, it probably works even though many Bash-only features will be turned off when it is invoked as sh
. But you shoud still understand the difference, and use bash
to run Bash scripts.)
Anyway, the preferred mechanism is to chmod +x
the script, and then simply run it by specifying its path (or just its name, if the directory it's in is on your PATH
). This allows the shebang to select the correct interpreter. (It's simply ignored as a comment if you explicitly run the script with sh
or bash
, or even something completely wrong like python
or csh
).
With these details fixed, your script would look like this.
#!/bin/bash
FTP_SERVER=ftp.ip
FTP_USER=ftp.user
FTP_PASS=ftp.passwd
FTP_DESTINATION_DIR="/destination_directory"
LOCAL_SOURCE_DIR="/home/$USER/pictures/local_pictures"
upload_file () {
local file=$1
echo "Hochladen von Datei $file"
ftp -inv "$FTP_SERVER" <<EOF
user $FTP_USER $FTP_PASS
binary
cd $FTP_DESTINATION_DIR
put $file
quit
EOF
}
export -f upload_file
find "$LOCAL_SOURCE_DIR" ( -name ".jpg" -o -name ".png" ) -exec bash -c 'upload_file "$0"' {} ;
A better fix still would be to allow upload_file
to accept multiple file names, and only create one FTP session.
:
upload_file () {
( printf '%s\n' \
"user $FTP_USER $FTP_PASS" \
"binary" \
"cd $FTP_DESTINATION_DIR"
local file
for file; do
# print diagnostics to stderr
echo "Hochladen von Datei $file" >&2
echo "put $file"
done
echo "quit" ) |
ftp -inv "$FTP_SERVER"
}
export -f upload_file
find "$LOCAL_SOURCE_DIR" ( -name ".jpg" -o -name ".png" )
-exec bash -c 'upload_file "$@"' _ {} +
Tangentially, probably don't use an .sh
extension on your shell scripts, especially if they are not actually sh
scripts. There is no strong convention around this, but ls
doesn't have an extension, either; why should it?