2017-08-17 62 views
-1

我想从远程服务器获取文件列表并将该列表放置在本地文件或数组中。遍历文件列表并从远程到本地一次获取每个文件。 但是,ls命令不能在远程服务器上运行,get命令不起作用。 下面是我的脚本:ls不工作在sftp korn外壳和命令不工作在循环内

#!/user/bin/ksh 
Sftp [email protected] <<EOF 
Cd source_path 
Set -A list_value $(ls source_path) 
for file in ${list_value[*]} 
do 
get /source_path/$file /dest_folder 
If ($? -eq 0); then 
rm /source_path/$file 
else 
echo "error" 
Exit 
fi 
done 
Bye 
EOF 

我甚至尝试

ls source_path > output.txt 

没有什么工作。在本地它使用数组,但for循环内的命令没有得到执行。在遥控器上没有工作。我甚至用echo *尝试并找到。它在ls附近抛出无效命令错误并得到。

+0

用四个空格前缀代码/数据。请看[编辑帮助](http://stackoverflow.com/editing-help)。 – Cyrus

+1

'sftp'有一个有限的命令集,我很确定它不包含'set','for/do/done','if/then/else/fi';是不是有一个原因,你不只是把一整套文件放在一个过程中,也就是说,为什么要存储在一个数组中,然后遍历数组呢? – markp

+0

是的,我需要在文件成功传输到本地文件夹后删除远程服务器中的文件。这就是原因,我试图一次拉出每个文件,而不是全部拉在一起。 – Kks

回答

0

假设:

  • 您想以后使用的文件名的数组的东西(否则我很可能只是直接喂ssh/find结果为while循环)
  • 您的远程主机可能的Solaris(不支持find/maxdepth),在这种情况下,我们必须使用一个有点时髦find命令效仿maxdepth=1
  • 你有你的帐户设置为允许无密码的ssh/scp电话

下面就做你想做的一种方式:

$ cat mycp 
#!/bin/ksh 

# replace `source_path' and 'dest_folder' accordingly 

remotedir=source_path 
localdir=dest_folder 

# the 'find' is a bit funky to allow us to emulate find/maxdepth if remote host is solaris 
# 'sed' command strips off the leading 2 characters (./) of the result 

set -A farray $(ssh [email protected] "cd ${remotedir} ; find . -name . -o -type d -prune -o -name '*' -print" | sed -r 's/^.{2}//') 

# iterate through the array 

for i in ${!farray[@]} 
do 
    # pull array element into variable => less typing for rest of loop 

    fname=${farray[${i}]} 

    # replace 'scp' with comparable 'sftp' if you wish 

    scp -p [email protected]:${remotedir}/${fname} ${localdir} 

    # if file exists locally, then remove remotely 

    [ -f ${localdir}/${fname} ] && ssh [email protected] "'rm' -rf ${remotedir}/${fname}" 
done 

反复回正与来回调用scp/ssh不完全是有效的,但编码是相当简单的。

更高效的过程需要多一点编码,但如果您不打算经常运行此过程或者使用相对较少的文件,则可能会过度使用。一种方法是这个样子:

  • 使用单一scp(或sftp/mget)命令靠边停车一次所有文件
  • 建立一个文件,你刚才复制的文件和地点的列表
  • scp(或sftp)文件名的文件返回给远程主机(例如在/tmp的地方)
  • ssh到远程主机上,并使用文件名的该文件驱动while/rm循环,当完成删除文件文件名称为
  • 结果:3个scp/ssh呼叫

以上的变化:

  • 使用单个scp(或sftp/mget)命令靠边一次所有文件
  • 的,而不是一个文件文件名,建立'rm'命令文件
  • scp'rm'命令到远程主机的文件/tmp
  • ssh远程主机和a)chmod 700'rm'文件,然后执行该文件或b)源'rm'文件;删除一旦做
  • 结果“RM”的文件:3个scp/ssh电话

“当然,如果你是在经常执行此操作计划也可能是值得的,看看你能得到2台主机设置了共享文件系统,因此不需要执行任何ssh/scp/sftp调用。

+0

谢谢markp。 你可以请建议,如果有一种方法来减少来回scp/ssh,因为我必须经常执行此操作。我只能执行sftp或scp,无法使用共享文件系统获取两台主机的设置。 – Kks

+0

我已经更新了一些关于如何减少后退的答案 – markp

+0

谢谢markp。我无法将变量传递给SSH脚本。你能帮忙吗?我将变量传递给ksh脚本,并在SSH中使用类似的变量。在$(cat'“$ 3/$ 4”')中的文件为SSH $ 1 @ $ 2';做rm'“$ 3”'/ $文件; done',其中$ 1,2,3,4是传递给korn shell的变量。 – Kks