【问题标题】:Concatenation of variable to end of URL in cURL for linux shell scriptlinux shell脚本cURL中将变量连接到URL末尾
【发布时间】:2021-04-23 21:56:51
【问题描述】:

(我针对 cme​​ts 对此进行了多次修改)

我的目标是有一个 shell 脚本去外部服务器,从目录中获取一批文件,在热敏收据打印机上打印它们,然后从远程服务器中删除相同的文件(这样当一个 cron作业运行,它们不会再次打印)。我的问题是将变量连接到 cURL 的 URL 末尾。脚本的其余部分正在运行,但为了清楚起见,我将显示整个脚本

我已经多次搜索解决方案,其中许多似乎涉及更复杂的情况,例如这个试图解决隐藏回车的问题,因为变量附加到 URL 的中间(c.f. Bash curl and variable in the middle of the url)。我尝试了那个解决方案(和其他几个),但它们没有用。我的情况更简单(我认为)所以也许这些答案增加了不必要的复杂性,这就是我的问题?总之……

这是包含敏感信息占位符的完整代码:

!/bin/bash
# step 1 - change to the directory where we want to temporarily store tickets
cd Tickets
# step 2 - get all the tickets in the target directory on the external server and put them in the current temporary local directory
wget --secure-protocol TLSv1_2 --user=<placeholder> --password='<placeholder>d' ftps://<placeholder>/public_html/tickets/*.txt
# step 3 - print each of the tickets in the current temporary local directory
for i in *.txt
do lp $i
done
# step 4 - reach out to the target directory and delete each of the files that we previously downloaded (not the entire directory; might have new files)
for i in *.txt
do curl --verbose --ftp-ssl --user <placeholder>:<placeholder> 'ftp://<placeholder>/public_html/tickets' -Q "DELE /public_html/tickets/$i"
done
# empty the current local directory where we temporarily stored files during the execution of this script
for i in *.txt
do rm $i
done
# should be done now.

我在第 4 步中使用了以下所有变体:

for i in *.txt
do curl --ftp-ssl --user (myftpid):(mypasswd) ftp://(myhostname)/public_html/tickets/ -Q 'DELE /public_html/tickets/'$i
done
for i in *.txt
do curl --ftp-ssl --user (myftpid):(mypasswd) ftp://(myhostname)/public_html/tickets/ -Q 'DELE /public_html/tickets/'${i}
done
for i in *.txt
do curl --ftp-ssl --user (myftpid):(mypasswd) ftp://(myhostname)/public_html/tickets/ -Q 'DELE /public_html/tickets/'"$i"
done
for i in *.txt
do curl --ftp-ssl --user (myftpid):(mypasswd) ftp://(myhostname)/public_html/tickets/ -Q 'DELE /public_html/tickets/'"${i}"
done

所有这四个的输出是:

curl: (21) QUOT command filed with 550

通过测试,我能够确认代码在没有变量的情况下工作:

curl --ftp-ssl --user <placeholder>:<placeholder> ftp://<placeholder>/public_html/tickets/ -Q 'DELE /public_html/tickets/14.txt'

*** 编辑 ** 我重新阅读了 cmets,我想我最初误解了其中的一些。我能够在 curl 命令前面使用 echo 来查看带有变量的输出。这非常有帮助,谢谢@Bodo。 @NationBoneless 对详细标签的建议也很有用,并产生了以下结果:

< 220-You are user number 1 of 50 allowed.
< 220-Local time is now 18:34. Server port: 21.
< 220-This is a private system - No anonymous login
< 220-IPv6 connections are also welcome on this server.
< 220 You will be disconnected after 30 minutes of inactivity.
AUTH SSL
< 500 This security scheme is not implemented
AUTH TLS
< 234 AUTH TLS OK.
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / <placeholder>
* Server certificate:
*  subject: CN=<placeholder>
*  start date: Nov 16 00:00:00 2020 GMT
*  expire date: Nov 16 23:59:59 2021 GMT
*  subjectAltName: host "<placeholder>" matched cert's "<placeholder>"
*  issuer: C=US; ST=TX; L=Houston; O=cPanel, Inc.; CN=cPanel, Inc. Certification Authority
*  SSL certificate verify ok.
USER <placeholder>
< 331 User <placeholder> OK. Password required
PASS <placeholder>
< 230 OK. Current restricted directory is /
PBSZ 0
< 200 PBSZ=0
PROT P
< 200 Data protection level set to "private"
PWD
< 257 "/" is your current location
* Entry path is '/'
DELE /public_html/tickets/14.txt
* ftp_perform ends with SECONDARY: 0
< 550 Could not delete /public_html/tickets/14.txt: No such file or directory
* QUOT command failed with 550
* Closing connection 0

【问题讨论】:

  • edit您的问题并添加更多详细信息:“没有一个有效”的确切含义是什么?显示确切的命令和相应的输出/结果/错误消息。要查看发生了什么,您可以在脚本中添加set -x 以打印命令或在curl 之前插入echo,即类似for i in *.txt; do echo curl --ftp-ssl ...
  • @Bodo - 我已经进行了请求的编辑。
  • 在不同变体中显示代码的简短 sn-p 并没有多大帮助。显示每个单独的完整命令和相应的结果。您仍然没有明确“没有工作”的确切含义。以哪种方式不起作用?您收到错误消息吗?意想不到的结果?完全没有结果?尝试两种建议的方法来显示将/将要执行的命令。如果您没有发现问题,请将输出添加到问题中。
  • @Bodo - 我已经进行了请求的编辑。
  • 详细输出显示DELE /public_html/tickets/14.txt,后跟550 Could not delete /public_html/tickets/14.txt: No such file or directoryDELE 协议命令看起来与我对带有硬编码文件名的 curl 命令的预期相同。此时文件是否存在?如果是,则可能某处存在隐形字符。您是否在终端和 Web 浏览器之间复制和粘贴代码和/或输出?根据所有四种情况的输出中的拼写错误,您可能重新输入了它,这可能会引入或隐藏错误。

标签: linux curl concatenation


【解决方案1】:

我认为这样的事情会奏效。当我在本地对其进行测试时,curl 命令似乎可以正常工作:

for i in *.txt
do curl --ftp-ssl --user (myftpid):(mypasswd) ftp://(myhostname)/public_html/tickets/ -Q "DELE /public_html/tickets/$i"
done

【讨论】:

  • 我刚刚测试了这种格式。它给出了与以前相同的错误。还有其他想法吗?
  • 你确定*.txt在那个目录中扩展的所有文件也在ftp服务器上吗?此外,您可以在 curl 命令中添加 --verbose 标志,以获取有关执行的更多信息。如果您可以从带有详细标志的命令中添加信息,那也将有助于查明错误
  • 我确定文件在那里。 --verbose 标志建议似乎很有帮助。我可以看到它说文件不存在。我猜我没有正确编写路径。我会稍微调整一下,看看我是否可以修复路径。
【解决方案2】:

首先,我要感谢@Bodo 和@NationBoneless。如果没有他们的 cmets,我不会想到这一点。非常感谢你们俩。

我的问题有两个部分 - 一个是连接问题(我从一开始就知道),还有我如何设置 curl 的 URL 路径(直到后来我才意识到)。

连接的正确形式是:

curl --ftp-ssl --user myID:mypassword 'ftp://host.mydomain.com' -Q "DELE /public_html/tickets/$i"

我在此过程中学到的一些要点可能对其他经验有限的人有用,包括:

  • 完全按照评论者的指示尝试,即使您认为自己理解他们的推理并且认为他们走错了路 - 他们可能没有错。
  • 如果您计划在引号内包含变量,请在 shell 脚本中使用双引号。单引号的行为非常不同,不能很好地处理变量。
  • echo是你的朋友;这对调试非常有帮助,因为 它向我表明,由于那些讨厌的单引号,我的变量被解析为 $i 而不是 $i 的值。谢谢@Bodo
  • --verbose 标志非常有用。它让我看到 curl 是 连接到服务器并且我的脚本失败了,因为它 找不到要删除的文件。我的 URL 路径错误,我没有 意识到。谢谢@NationBoneless
  • 我最初将完整路径放在ftp: 部分,然后再次 在-Q 之后,但这不起作用。经过多次试验和错误,我明白了 在-Q 之前只使用ftp:hostname 和其余的 -Q 之后的路径。
  • 下一部分可能不适用于其他任何人,但我是服务器 正在使用 WHM/cPanel。我正在尝试的域 connect 实际上不是我在代码中使用的域。我不得不 连接到 host.myserverdomain.com(我用于 root 的域 WHM 中的管理内容)而不是 ftp.thisprojectdomain.com(域 我实际工作的地方)。显然可以设置WHM/cPanel 很多方式,这就是我的数据中心设置我的方式。不知道如何 这很常见,但如果你把头发扯掉,试着换成 WHM 域。
  • 对于那些想知道为什么我的主脚本同时使用 wget 和 curl 的人;一世 从 wget 开始,因为我认为我更熟悉它。 wget 无法删除服务器上的文件。我切换到 curl 来删除 文件,但从未将第一条语句切换为 curl,因为它 工作。可能有一种方法可以使用 curl 而不是 wget;我离开 该练习到 cmets 部分,因为我会坚持使用有效的方法。

【讨论】:

  • 没有正确的形式,其他一些变体应该也可以。例如'DELE /public_html/tickets/'"$i"'DELE /public_html/tickets/'"${i}" 应该等价于"DELE /public_html/tickets/$i"。一般来说,根据您的需要使用正确的引用形式很重要。双引号和单引号都有各自的用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多