LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   calling lftp from a bash script; howto pass variables into the command syntax (http://www.linuxquestions.org/questions/programming-9/calling-lftp-from-a-bash-script%3B-howto-pass-variables-into-the-command-syntax-4175444669/)

stvy 01-08-2013 10:35 AM

calling lftp from a bash script; howto pass variables into the command syntax
 
Hi,

I am attempting to call the lftp program from a bash script. I would like to do something like this:

/usr/bin/lftp -c 'open -e "mirror --ignore-time --no-perms ${SRC_DIR} ${DST_DIR}" ${USERNAME}:${PASSWORD}@${IP_ADDRESS}' >> ${REPORT_DIR}/${IP_ADDRESS}-lftp-server.log 2>> ${REPORT_DIR}/${IP_ADDRESS}-lftp-server.err

However the variables are not correctly being replaced with there values which are defined elsewhere. The issue is I beleive related to the requirement for the use of ' and " charachters in the syntax of the lftp command.

Can someone propose a method to solve this problem?

Thanks,
Stvy

colucix 01-08-2013 02:30 PM

Quote:

Originally Posted by stvy (Post 4865463)
The issue is I beleive related to the requirement for the use of ' and " charachters in the syntax of the lftp command.

That's correct. Single quotes around the lftp command prevent any shell substitution. I usually do something like this:
Code:

(
 echo open ip_address
 echo user username password
 echo put -O $today $file_gnome_curr
 echo bye
) | lftp -f /dev/stdin >> lftp.log 2>&1

Just to show it echoes the commands in a subshell and pipes the list as standard input to lftp. Hope this helps.

David the H. 01-09-2013 01:43 PM

Please use ***[code][/code]*** tags around your code and data, to preserve the original formatting and to improve readability. Do not use quote tags, bolding, colors, "start/end" lines, or other creative techniques.


Read these three links for the full rundown on how the shell parses arguments. It's a vital concept in scripting, so learn it well!

http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes

Also see the QUOTING section of the bash man page.


To start with, stop thinking about quotes as enclosures, and consider them more like toggle switches. One instance turns escaping on, and the next turns it off.

(There are a few exceptions to this. Quotes inside of subshells, embedded commands, and parameter substitutions, for example, are treated separately, i.e. running in a different parsing environment. But even then they behave normally inside their respective nestings.)

The ', or hard quote, will escape everything after it until it hits another '. The ", or soft quote, will escape everything except $,\, and `, (and "!" when history expansion is enabled) until it hits the next ". This allows variable expansion and embedded commands to continue to work inside them.

Notice too how the two quote types interact. The hard quote is escaped by soft quotes, and vice-versa. Also, since \ is still special inside soft quotes, you can manually escape any of the still-special characters listed above, as well as other "s, if necessary.


Now, in your particular case, what you need to do is format the entire block so that it comes out as a single "word" token, while also allowing the variables to expand inside it.

I think the easiest way is to simply enclose the whole command string in double quotes, then go through and backslash-escape the other double quotes inside it as needed.

I also recommend rearranging your code to separate the command you send (the data) from the command you run (the code), by storing the first one in a variable first. This will help to keep things readable and avoid some of common gotchas.

I would even do this with the output files too, to further shorten up the code for readability. And remove the "{}"'s, too. They're pointless most of the time and just make the code harder to read.

Code:

logfile="$REPORT_DIR/$IP_ADDRESS-lftp-server.log"
errfile="$REPORT_DIR/$IP_ADDRESS-lftp-server.err"

command="open -e \"mirror --ignore-time --no-perms $SRC_DIR $DST_DIR\" \"$USERNAME:$PASSWORD@$IP_ADDRESS\""

/usr/bin/lftp -c "$command" >> "$logfile"  2>> "$errfile"


PS: Since environment variables are generally all upper-case, it's good practice to keep your own user variables in lower-case or mixed-case to help differentiate them.


All times are GMT -5. The time now is 05:56 AM.