我正在尝试使用curl 通过FTP 将当前文件夹中的所有文本文件上传到服务器位置。我尝试了以下行:
curl -T "{file1.txt, file2.txt}" ftp://XXX --user YYY
其中 XXX 是服务器的 IP 地址,YYY 是用户名和密码。
我能够成功地将 file1.txt 传输到服务器,但它抱怨第二个文件说“无法打开‘file_name’!”
我交换了文件名,它适用于 file2.txt 而不是 file1.txt。好像我的语法错误,但这就是手册所说的?
另外,理想情况下我能够做这样的事情:
curl -T *.txt ftp://XXX --user YYY
因为我并不总是知道当前文件夹中的txt文件的名称或要传输的文件的数量。
我认为我可能需要编写一个 bash 脚本,将 的输出收集ls *.txt
到一个数组中,并将其放入curl 所需的多文件格式中。
我以前没有编写过 bash 脚本 - 这是实现此目的的最简单方法吗?
答案1
您的第一个命令应该在没有空格的情况下运行:
curl -T "{file1.txt,file2.txt}" ftp://XXX/ -user YYY
另请注意上面 URL 中的尾部“/”。
这是curl关于选项“-T”的手动条目:
-T, --上传文件
这会将指定的本地文件传输到远程 URL。如果指定的 URL 中没有文件部分,Curl 将附加本地文件名。请注意,您必须在最后一个目录上使用尾随 / 来真正向 Curl 证明没有文件名,否则curl 会认为您的最后一个目录名是要使用的远程文件名。这很可能会导致上传操作失败。如果在 HTTP(S) 服务器上使用此命令,则将使用 PUT 命令。
使用文件名“-”(一个破折号)来使用 stdin 而不是给定文件。或者,文件名“.”可以指定(单个句点)而不是“-”以在非阻塞模式下使用 stdin,从而允许在上传 stdin 时读取服务器输出。
您可以在命令行上为每个 URL 指定一个 -T。每个 -T + URL 对指定要上传的内容和位置。 curl 还支持 -T 参数的“通配”,这意味着您可以使用 URL 中支持的相同 URL 通配样式将多个文件上传到单个 URL,如下所示:
curl -T "{file1,file2}" http://www.uploadtothissite.com
甚至
curl -T "img[1-1000].png" ftp://ftp.picturemania.com/upload/
“*.txt”扩展不起作用因为curl仅支持与URL相同的语法:
您可以通过在大括号内编写部分集来指定多个 URL 或 URL 的一部分,如下所示:
http://站点.{一,二,三}.com
或者您可以使用 [] 获取字母数字系列的序列,如下所示:
ftp://ftp.numerics.com/file[1-100].txt
ftp://ftp.numericals.com/file[001-100].txt (带前导零)
ftp://ftp.letters.com/file[az].txt
[...]
当从命令行提示符调用时使用 [] 或 {} 序列时,您可能必须将完整的 URL 放在双引号内,以避免 shell 干扰它。这也适用于其他特殊对待的字符,例如“&”、“?”和 '*'。
但你可以使用“正常”的 shell 通配符,如下所示:
curl -T "{$(echo *.txt | tr ' ' ',')}" ftp://XXX/ -user YYY
(最后一个示例可能不适用于所有 shell 或任何类型的外来文件名。)
答案2
您可以使用“查找”实用程序依次对每个文件调用curl:
find . -name '*.txt' -exec curl -T {} ftp://XXX --user YYY \;
答案3
您可以映射所有 .txt 文件,然后将所有外来文件名上传到您的 ftp 服务器:
1 - 使用映射文件映射您要上传的所有文件并将它们存储在文件名变量中
使用示例
#将输出捕获到数组中:
$ mapfile GEEKSFORGEEKS < <(printf "项目 1\n项目 2\n项目 3\n") $ echo ${GEEKSFORGEEKS[@]}
这里,Item1、Item2和Item 3已存储在数组GEEKSFORGEEKS中。
在这里查看更多内容:[geeksforgeeks][2]
2-创建一个循环来读取文件名数组中存储的所有文件,并检查它们是否已经存在($i -lt ${#filenames[@]}
),然后上传到 ftp,通配所有外来文件名(-g),静默(-s)(仅输出到标准输入错误 - )
我在控制台中测试了自己,它工作得很好
filenames=(); mapfile -d '' filenames < <(find . -name '*.txt' -type f -print0)
i=0; for f in ${filenames[@]}; do [[ $i -lt ${#filenames[@]} ]] && curl -g -s -S -T "${f}" ftp://XXX/ -user YYY; i=$i+1; done
[2]: https://www.geeksforgeeks.org/mapfile-command-in-linux-with-examples/#:~:text=mapfile%20also%20称为%20(读取%20array,比较%20to%20a% 20读取%20循环。