.png)
これに関連する質問はたくさん見られますが、私の制約がすべてではないので、まずは私の制約から始めます。
制約:
- リモートディレクトリを再帰的にコピーしたい。
- リモート サーバーの設定をまったく制御できません。
- リモート マシン上のそのディレクトリへの書き込み権限がありません。
- 試してみると
get -r
、ディレクトリがコピーされますローカルなし書き込み権限もありません。 - その後、リモートディレクトリ内のネストされたファイルやフォルダを再帰的にコピーしようとすると、地元書き込み権限が与えられなかったディレクトリ。
- マシンに新しいソフトウェアをインストールできません。(
sftp
「OpenSSH_7.9p1、LibreSSL 2.7.3」を使用した純粋なソリューションが必要です)
質問:
sftp
pureとnoを使用してリモートディレクトリを再帰的にコピーできますか?地元権限エラーですか?
答え1
アップデート: 2021-03にリリースされたOpenSSH 8.5ではこの問題が修正されています。http://www.openssh.com/txt/release-8.5バグ修正の下にある 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 ではテストしていませんが、特に記載がない限り、ここにあるものはすべて移植可能であると考えています。)