【问题标题】:Multi-variable string not being returned via SFTP get command未通过 SFTP get 命令返回多变量字符串
【发布时间】:2019-09-03 06:38:39
【问题描述】:

我正在编写一个 ksh 脚本,通过 sftp 每小时检索一个文件,该文件将放在作业调度程序上,每小时运行一次。该脚本必须导航到具有昨天日期的文件夹 (remote/path/yyyymmdd/)。文件名还有昨天的日期和时间戳(filename_yyyymmdd_hhmmss.dat)。由于作业将被安排,我的脚本必须包括前一小时 - 例如。如果作业在 11:02 运行,则要检索的文件将为 filename_yyyymmdd_10mmss.dat。分钟和秒将始终相同 - 例如 4949。远程目录中将有多个文件,我只想检索最新的文件,这样我们的作业就不会处理多个输入文件。远程目录还会定期创建其他文件,因此我无法仅检索最后修改的文件。

我有返回昨天的日期和前一小时的变量,但是 sftp 命令没有返回完整的文件名,也没有检索文件。我尝试连接变量,使用括号和引号和括号,将多个变量分配给单个变量,然后导出变量。

vdate=$(TZ=bb24 date '+%Y%m%d')
vhour=$(date '+%H')
prevhour=$((vhour - 1))

sftp user@host << EOF
lcd /my/dir/
cd /remote/path/$vdate/
get filename_$vdate_$prevhour*.dat
bye
EOF
exit

运行脚本时,找不到文件且文件名不完整 返回:

File "/remote/path/20190411/filename_20190411" not found.

而不是

File "/remote/path/20190411/filename_20190411_10*.dat" not found.

我尝试的每个变量组合都返回相同的未找到 - 在 filename_$vdate 之后结束。

我尝试了其他一些组合,但总是找不到相同的组合:

newvar=${vdate}_${prevhour}
get filename_$newvar*.dat

newvar=${vdate}\\_${prevhour}
get filename_$newvar*.dat
File "/remote/path/20190411/filename_20190411" not found.

【问题讨论】:

  • *(s)ftp 客户是出了名的问题(我没说有问题:-))。您的代码看起来应该可以工作。我会手动运行sftp 并输入每个cmd。当您到达 get file... 时,我会将其替换为 dir file...* 和 1. 确认文件确实存在 2. 看看您是否发现了 filename_$vdate_$prevhour*.dat 无法正常工作的某些原因。如果您可以通过手动输入所有内容来使其工作,那么您必须查看ksh 正在处理的内容。在 here-doc 中更难做。 ....
  • 啊,也许你需要使用mget,即使只有一个文件。 * 可能会把它扔掉。 .... 否则,在单独的终端窗口中,手动执行对filename_$vdate_$prevhour*.dat 的分配,然后在命令行上执行echo filename_$vdate_$prevhour*.dat 并将该值复制/粘贴到您的sftp 会话中。祝你好运!
  • 请尝试使用这种格式get filename_${vdate}_${prevhour}*.dat
  • @shellter @edvin 我尝试了这两种方法,但都不成功。手动运行命令并回显返回所需的输出,但是一旦我通过 sftp 手动输入命令,输出就会不匹配。 sftp客户端中的变量数量是否有字符限制或限制?我最终可能只是检索filename* 并让脚本删除不是前一小时的副本。

标签: shell concatenation ksh


【解决方案1】:

prevhour=$((vhour - 1)) 的脚本有问题 这样一个文本02在你做减法后,它将是1而不是01,它将匹配不需要的文件,甚至没有,因为00 - 1-1

[edvin]$ vdate=$(TZ=bb24 date '+%Y%m%d')
[edvin]$ vhour=$(date '+%H')
[edvin]$ prevhour=$((vhour - 1))
[edvin]$ echo $vhour
03
[edvin]$ echo $prevhour
2
[edvin]$ prevhour=$(date -d '1 hour ago' '+%H')
[edvin]$ echo $prevhour
02

日期的-d 选项在某些系统上不可用。

我相信在您的尝试中,shell 被认为是 * 变量 prevhour 的一部分,因为您没有将其放入 {} 中以将变量与相关文本分开。

这是我基于您的尝试的工作解决方案:

#!/bin/ksh

r_host='server2'
r_user='edvin'
l_dir='./content'
r_dir='./Test_folder'

# this still not cover the case of midnight
# it put 00 to 23 but day have to be yesterday as well
##vdate=$(TZ=bb24 date '+%Y%m%d')
##vhour=$(date '+%H')                      # not used
##prevhour=$(date -d '1 hour ago' '+%H')

# vtime = YYYYmmdd_HH -1 H
vtime=$(TZ=bb24 date -d '1 hour ago' '+%Y%m%d_%H')

sftp ${r_user}@${r_host} << EOF
lcd ${l_dir}
cd ${r_dir}
get filename_${vtime}*.dat
bye
EOF

exit

输出:

[edvin]$ ./script.ksh 
Connected to server2.
sftp> lcd ./content
sftp> cd ./Test_folder
sftp> get filename_20190415_02*.dat
Fetching /home/edvin/Test_folder/filename_20190415_020000.dat to filename_20190415_020000.dat
Fetching /home/edvin/Test_folder/filename_20190415_020100.dat to filename_20190415_020100.dat
Fetching /home/edvin/Test_folder/filename_20190415_020200.dat to filename_20190415_020200.dat
Fetching /home/edvin/Test_folder/filename_20190415_020300.dat to filename_20190415_020300.dat
Fetching /home/edvin/Test_folder/filename_20190415_020400.dat to filename_20190415_020400.dat
Fetching /home/edvin/Test_folder/filename_20190415_020500.dat to filename_20190415_020500.dat
Fetching /home/edvin/Test_folder/filename_20190415_020600.dat to filename_20190415_020600.dat
Fetching /home/edvin/Test_folder/filename_20190415_020700.dat to filename_20190415_020700.dat
Fetching /home/edvin/Test_folder/filename_20190415_020800.dat to filename_20190415_020800.dat
Fetching /home/edvin/Test_folder/filename_20190415_020900.dat to filename_20190415_020900.dat
Fetching /home/edvin/Test_folder/filename_20190415_021000.dat to filename_20190415_021000.dat
sftp> bye

这个解决方案仍然有很多问题, 就像如果远程目录不存在,不可访问,脚本仍然会继续执行命令的其余部分,本地目录和文件也是如此。该连接还可以运行您可能想要处理的各种问题。您喜欢安排它,因此可能需要一种解决方案来避免脚本在已经运行的情况下一遍又一遍地产生。

scp 将是更优选的方式,因为您使用无密码身份验证。

如果由于某种原因scp 不是一个选项,使用expect 可以很好地处理。

【讨论】:

  • 我最终选择了mget *.dat,然后在退出 sftp 后使用ls -1 filename*.dat | sort -r | tail +2 | xargs -i rm {} 根据文件名中的时间戳删除除最新版本之外的所有版本。我无法通过 sftp 正确执行命令。
猜你喜欢
  • 1970-01-01
  • 2013-09-15
  • 1970-01-01
  • 2017-07-16
  • 1970-01-01
  • 2015-11-20
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
相关资源
最近更新 更多