我看到很多与此相关的问题,但并非全部涉及我的限制,因此我将从我的限制开始。
限制:
- 我想递归复制远程目录。
- 我根本无法控制远程服务器设置。
- 我没有远程计算机上该目录的写权限。
- 当我尝试时
get -r
,它会复制目录无本地写入权限。 - 然后,当它尝试递归复制远程目录中的嵌套文件和文件夹时,它会在当地的它没有授予我写权限的目录。
- 我无法在我的计算机上安装新软件。(需要一个
sftp
带有“OpenSSH_7.9p1,LibreSSL 2.7.3”的纯解决方案)
问题:
sftp
我可以使用 pure和 no递归复制远程目录吗当地的权限错误?
答案1
更新:OpenSSH 8.5 于 2021-03 发布,修复了此问题;请参阅http://www.openssh.com/txt/release-8.5在 Bugfixes 下为 bz#3222 的项目。
另外:OpenSSH 7.9 于 2018 年 10 月发布;它不可能“大约 5 年前在 Mac 上出现”。不知何故,你已经更新了。
您说得对;如果可用,download_dir_internal
则创建sftp-client.c
一个新的本地目录,其权限与远程目录相同,但被 01777 屏蔽 - 即排除 suid 和 sgid,这非常罕见,很可能不会发生在您的案例中。需要-p
(或-P
) 标志来设置权限文件但对于目录来说会被忽略。
但是,如果目录已经存在,sftp 将忽略 EEXIST 错误。因此,如果您首先创建所有(空)目录和写入权限然后执行get -r
它应该可以工作。我没有看到任何在 sftp 中列表递归地,所以除非你已经知道目录结构或者有办法find /mydir -type d
在远程执行类似的事情,否则这会变得有点丑陋:
#!/bin/bash # or other location as necessary
REMOTE=(user@host) # array so can add _separated_ options like -i idfile -P port if needed
IFS=$'\n'
all=( )
new=( $( echo ls -n | sftp ${REMOTE[@]} | awk '/^d/{print substr($0,57)}' ) )
while [[ ${#new[@]} -gt 0 ]]; do
all+=( "${new[@]}" )
new=( $( printf "ls -n %s\n" "${new[@]}" \
| sftp ${REMOTE[@]} | awk '/^d/{print substr($0,57)}' ) )
done
mkdir "${all[@]}" # with umask NOT including 200!
# or if (maybe) large enough to hit ARG_MAX
printf '%s\n' "${all[@]}" | xargs mkdir
# if dirnames (can) contain any SP TAB " ' \
# use -d'\n' on GNU but you're on your own otherwise
# (and Macs mostly don't have GNU)
(我没有 Mac,因此未在 Mac 上测试,但我相信除另有说明外,这里的所有内容都是可移植的。)