提问者:小点点

在linux外壳脚本的cURL中将变量连接到URL的末尾


(为了回应评论,我对此进行了多次编辑)

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

我已经为解决方案做了几次搜索,许多似乎涉及更复杂的情况,例如,这一个试图解决隐藏的回车,因为变量被追加到URL的中间(C.F.Bash CURL和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'

***编辑**我重新阅读了评论,我想我最初误解了其中一些。我可以在curl命令前面使用echo来查看变量的输出。这很有帮助,谢谢@Bodo。来自@National Bonless的关于冗长标签的建议也很有用,并产生了以下内容:

< 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

共2个答案

匿名用户

我想这样的事情会管用的。在本地测试时,curl命令似乎工作正常:

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

匿名用户

首先,我要感谢@Bodo和@NationBoneless。如果没有他们的评论,我是不会明白这一点的。非常感谢你们两位。

我的问题有两个部分——一个是串联的问题(我从一开始就知道),还有我如何为curl设置网址路径的问题(我直到后来才意识到)。

连接的正确形式为:

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

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

  • 尝试评论者让你尝试的东西,即使你认为你理解他们的推理,你认为他们在错误的轨道上——他们可能没有错。
  • 如果计划在引号中包含变量,则对shell脚本使用双引号。单引号的行为非常不同,不能很好地处理变量。
  • echo是你的朋友;它对调试非常有帮助,因为它告诉我,由于那些讨厌的单引号,我的变量被解析为$i,而不是$i的值。感谢@Bodo
  • -详细标志非常有用。它让我看到curl正在连接到服务器,我的脚本失败了,因为它找不到要删除的文件。我的网址路径是错误的,我没有意识到。感谢@无骨民族
  • 我最初把完整的路径放在ftp:部分,然后再放在-Q之后,但那不起作用。经过多次试验和错误,我让它只在-Q之前使用ftp: host name,在-Q之后使用其余路径。
  • 下一部分可能不适用于其他人,但我正在使用的服务器是WHM/cPanel。我试图连接的域实际上不是我在代码中使用的域。我必须连接到host.myserverdomain.com(我在WHM中用于根管理的域)而不是ftp.thisprojectdomain.com(我实际工作的域)。显然,WHM/cPanel可以通过多种方式设置,这就是我的数据中心设置我的方式。不知道这有多常见,但是如果你要把头发扯掉,试着切换到WHM域。
  • 对于那些想知道为什么我的主脚本同时使用wget和curl的人;我从wget开始,因为我认为我更熟悉它。wget不能删除服务器上的文件。我切换到curl删除文件,但从来没有切换到curl的第一个语句,因为它的工作。可能有一种方法可以使用curl而不是wget;我把这个练习留给评论部分,因为我会坚持使用有效的方法。

相关问题