I've created a script to upload via lftp:
#! /usr/bin/bash
set -xe
if [ -n "$1" ]; then
...
else
source="."
target=name of current local folder
target="${PWD##*/}"/
cmd="mirror --reverse --continue --parallel=5 "$source" "$target""
fi
lftp -u $user,$pass $host << EOF
set log:enabled true
eval "$cmd"
quit
EOF
If the current directory does not contain spaces, this works correctly. The problem occurs when the current directory does have spaces. Here is what the debug information shows:
➜ upload.sh
+ '[' -n '' ']'
+ source=.
+ target='Two Words/'
+ cmd='mirror --reverse --continue --parallel=5 . Two Words/'
As a result of this issue, the script uploads to directory named Two
instead of Two Words
.
I'm not sure how to fix this problem, especially because I don't know which line is where I went wrong: cmd=...
? eval "$cmd"
? Neither? Both?
Regardless, I was expecting that debug output to look like this: + cmd='mirror --reverse --continue --parallel=5 "." "Two Words/"'
(notice the double quotes) and I'm not sure why it didn't.
This question is similar to a lot of others I researched to get this far. What makes this different/hard to Google is that the expansion is happening inside of a "here string". For all I know that's irrelevant, but for all I know it could be critically unique, too.
Comments suggested I store everything into an array. Here's my attempt to do so:
#! /usr/bin/bash
set -xe
if [ -n "$1" ]; then
cmd=(mput -c -P 5 "$1")
if [ -n "$2" ]; then
cmd=(mkdir -p "$2"
mput -c -P 5 -O "$2" "$1") #*
fi
else
source="."
target=name of current local folder
target="${PWD##*/}"/
cmd=(mirror --reverse --continue --parallel=5 "$source" "$target")
fi
lftp -u $user,$pass $host << EOF
"${cmd[@]}"
quit
EOF
(* I can't figure out how to have multilines in a subshell. That's why I put actual newlines in there, but I'm not sure if that's the correct thing to do. Every result I google has to do with command substitution, not subshells.)
When I run this, it gives me this error: Unknown command 'mirror --reverse --continue --parallel=5 . Two Words/'.
If I copy and paste that into my shell, it gives me a different error, so I'm not understanding what's going on.
Calling lftp -u $user,$pass $host -e "${cmd[@]}"
didn't work either. That gives this error:
open: unrecognized option '--reverse'
Usage: lftp [-e cmd] [-p port] [-u user[,pass]] <host|url>
running lftp ... -e "$("${cmd[@]}")"
gave this error:
open: option requires an argument -- 'e'
Usage: lftp [-e cmd] [-p port] [-u user[,pass]] <host|url>
As you can see, at this point, I'm just trying random stuff and hoping it'll provide insight. Not a good strategy.
cmd=
lines tocmd=(...)
lines, then replaced theeval ...
with"${cmd[@]}"
, it gave me this error:Unknown command 'mirror --reverse --continue --parallel=5 . Two Words/'.
– Daniel Kaplan Apr 09 '22 at 00:16