添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
俊逸的冲锋衣  ·  verilog中,if ...·  2 月前    · 
听话的机器猫  ·  sqlite wal 分析 - 掘金·  8 月前    · 
憨厚的鼠标  ·  Hadoop Streaming ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am writing a bash script to download files from ftp server using lftp. I wanted to delete the files based on the second input argument.

#!/bin/bash
cd $1
lftp -u found,e48RgK7s sftp://ftp.xxx.org << EOF
set xfer:clobber on
mget *.xml
if [ $2 = "prod"]; then
  echo "Production mode. Deleting files"
  mrm *.xml
  echo "Non-prod mode. Keeping files"

However, if statement is not allowed in the lftp block before EOF.

Unknown command `if'.
Unknown command `then'.
Usage: rm [-r] [-f] files...
Unknown command `else'.

How do I embed if statement in such block?

BTW, [ $2 = "prod" ] is quoting exactly the wrong thing: prod doesn't need to be quoted (it can only be parsed one way, as a single word), but $2 could evaluate to any number of shell words, and thus any number of arguments to [, if not quoted. This is a category of issue that shellcheck.net can find. – Charles Duffy Dec 27, 2016 at 20:01 if [ "$mode" = "prod" ]; then echo "Production mode. Deleting." >&2 # this is logging (because of >&2) echo "mrm *.xml" # this is substituted into the heredoc echo "Non-prod mode. Keeping files" >&2

Note that inside the substitution for the heredoc, we're routing log messages to stderr, not stdout. This is essential, because everything on stdout becomes a command substituted into the heredoc sent to lftp.

Other caveats to command substitution also apply: They run in subshells, so a assignment made inside the command substitution will not apply outside of it, and there's a performance cost to starting them.

A more efficient approach is to store your conditional components in a variable, and expand it inside the heredoc:

case $mode in
  prod)
    echo "Production mode. Deleting files" >&2
    post_get_command='mget *.xml'
    echo "Non-production mode. Keeping files" >&2
    post_get_command=
lftp ... <<EOF
set xfer:clobber on
mget *.xml
$post_get_command
                Thanks for pointing out. No wonder it does not work when I direct to &1. That explains it.
– ddd
                Dec 28, 2016 at 16:43
                The || exit ensures that we don't proceed to run the rest of the script if the cd fails. You probably don't want to risk downloading files into the wrong directory, right?
– Charles Duffy
                Dec 28, 2016 at 16:45
                I don't really see the point of the all this inside the here-doc. Wouldn't it be better to put the logic outside of the here-doc? what's the advantage of your design? (I only see disadvantages).
– gniourf_gniourf
                Dec 28, 2016 at 17:05
                @gniourf_gniourf, readability -- it allows the overall control flow to be seen in context, rather than dereferencing a variable in the heredoc and needing to refer elsewhere to see how it's assigned. And it is what the OP quite literally asked for. That said, there's value to showing an alternate, more efficient approach as well.
– Charles Duffy
                Dec 28, 2016 at 17:38
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.