ssh
( net/ssh )を介してRuby
を使用してリモートスクリプトを実行し、フォルダーを再帰的にコピーしてサブフォルダーを除外する必要があります。私はそれを行う最速の方法を探しているので、rsync
は良くありません。また、ssh
はsh
ではなくbash
を使用することも理解しています。
バッシュで私はします:
cp -r srcdir/!(subdir) dstdir
そしてそれはうまく働きます。しかし、ssh
を介してスクリプトを起動すると、エラーが表示されます
sh: 1: Syntax error: "(" unexpected
sh
を使用しているためです。
sh
のマニュアルページを確認しましたが、ファイルを除外するオプションがありません。
ssh
を使用したsh
の私の仮定は正しいですか?代替案はありますか?
EDIT 1:役立つ場合、Sudo cat /etc/shells
の出力は次のようになります。
# /etc/shells: valid login shells
/bin/sh
/bin/dash
/bin/bash
/bin/rbash
/usr/bin/tmux
/usr/bin/screen
編集2:OK。だからbashは利用可能で、それは問題ではないようです。 sshが実際にbash
を使用していることを確認しました。この問題は、括弧または感嘆符のエスケープに関連しているようです。シェル(macos)からコマンドを実行しようとしましたが、これが実際のコマンドです。
ssh -i .ssh/key.pem [email protected] 'mkdir /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; cp -r /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!\(constant\) /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; ln -s /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/constant /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N/constant'
このようにして、別のエラーを受け取ります
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
EDIT 3:コメントに基づいて、extglob
を追加してコマンドを変更しました
私が使うなら
ssh -i .ssh/key.pem [email protected] 'shopt -s extglob; mkdir /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; cp -r /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!\(constant\) /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N; ln -s /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/constant /home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/N/constant'
次のエラーが表示されます。
cp: cannot stat '/home/ubuntu/OpenFOAM/ubuntu-4.1/run/LES_New-Area_residuals2/mesh/!(constant)': No such file or directory
かっこをエスケープしないと、
bash: -c: line 0: syntax error near unexpected token `('
SSHは、リモートシステムでログインシェルを実行します。ただし、!(foo)
にはshopt -s extglob
が必要です。これはリモートで設定していない可能性があります。
これを試して、SSHがリモート側でBashを実行しているかどうかを確認します。
ssh me@somehost 'echo "$BASH_VERSION"'
何も出力されても、起動スクリプトでextglob
が設定されていない場合は、ssh
に渡されたコマンドを手動で実行できます。
ssh me@somehost 'shopt -s extglob
echo srcdir/!(subdir)'
# or
ssh me@somehost $'shopt -s extglob\n echo srcdir/!(subdir)'
extglob
はコマンドラインの解析に影響し、改行の後にのみ有効になるため、リテラルの改行をそこに配置する必要があります。セミコロンでは不十分です。
ssh me @ somehost 'shopt -s extglob; echo srcdir /!(subdir) '
また、バックスラッシュで括弧をエスケープすると、他のグロブ文字と同様に、特別なプロパティが失われます。これは、この場合にしたいことではありません。
$ touch foo bar; shopt -s extglob; set +o histexpand
$ echo *
bar foo
$ echo !(foo)
bar
$ echo \*
*
$ echo !\(foo\)
!(foo)
Rsyncが遅いと思う理由がわかりません。コピーの速度は、主にディスクの速度によって決まります。 Rsyncには、含めるものと除外するものを指定する多くのオプションがあるため、シェルグロビングよりもはるかに優れた制御が可能です。
Bashマニュアルに記載されているように、extglob
が設定されている場合、!(patter)
はbashでのみ認識されます。あなたの例では、extglob
を設定していません。さらに、bash
として開始されたsh
はbash
のままですが、互換性のために一部の拡張機能を無効にします。
SSHサーバーは、/etc/passwd
で指定されているように、ユーザーのログインシェルを起動します。シェルを変更するか、そのシェルを使用して、ニーズにより適した別のシェルを起動できます。
最初にいくつかのメモ:
sh
を開始せず、リモートホスト上のユーザーのログインシェルをthat-Shell -c <the-string-provided-by-the-client>
として実行します。リモートユーザーのログインシェルは何でもかまいません。 tcsh
、fish
、rc
などの一部のシェルは、sh
とは非常に異なる構文を持っていることに注意してください。ssh Host cmd arg1 'arg 2'
を実行しても、cmd
、arg1
、およびarg 2
は、ssh
に渡される3つの引数であり、ssh
は、これらの引数をスペースで連結し、cmd arg1 arg 2
文字列を実際にsshd
、リモートシェルはそれをcmd
、arg1
、arg
、2
に分割します。!(subdir)
はグロブ演算子です(ksh
グロブ演算子もzsh -o kshglob
およびbash -O extglob
でサポートされています)。すべてのグロブと同様に、隠しファイルを除外するため、除外する他のファイルがある可能性があることに注意してください。ここでは、リモートシェルの正しい構文を見つけることによる問題を回避するために、実際に他のシェルに必要なシェルを起動して、stdin( How toリモートユーザーのログインシェルを知らずにsshで任意の簡単なコマンドを実行しますか? )
ssh Host 'bash -O extglob -O dotglob' << 'EOF'
cp -r srcdir/!(subdir) dstdir/
EOF
bash -O extglob -O dotglob
は、Bourne系のシェル、csh、rc、fishなど、すべての主要なシェルで同じように理解されるコマンドラインです。上記は、bash
がインストールされ、ユーザーの$PATH
にある限り機能します。 (デフォルトの$PATH
、zsh
の場合は~/.zshenv
、csh
の場合は~/.cshrc
、bash
の場合は~/.bashrc
など、ユーザーのログインシェルによって変更される可能性があります)。
POSIXly(実際には、より多くのシステムがbash
コマンドよりもpax
コマンドを持っていることに気付くかもしれません)、あなたはそうすることができます:
ssh Host sh << 'EOF'
cd srcdir && pax -rw -'s|^\.//\./subdir\(/.*\)\{0,1\}$||' .//. /path/to/destdir/
EOF
-s
は、転送されるパスに置換を適用します。その置換が何にも拡張されない場合、ファイルは除外されます。問題は、置換がシンボリックリンクのターゲットにも適用されることです。そのため、上記の.//.
を使用して、シンボリックリンクが影響を受ける可能性を低くしています。
ssh
がsh
の使用に限定されているとは思いません。ターゲットシステムに何がインストールされているか、ユーザーがどのように設定されているか、/etc/shells
で許可されているシェルに依存します。
chsh
コマンドを検討しましたか?
これをすばやく実行したい場合は、別の暗号化アルゴリズムを使用してrsync
を調べることができます。これにより、それほど速度を犠牲にすることなく、簡単に除外するなどのオプションが提供されます。
rsync -aHAXxv --numeric-ids --progress -e "ssh -T -c arcfour -o Compression=no -x" user@<source>:<source_dir> <dest_dir>
/etc/ssh/ssh_config
のarcfour
で始まる行にCiphers
暗号化を追加すると、まだ有効になっていない場合は、許容可能な速度が得られます。
警告:arcfour
の暗号化はinsecureです。安全でないチャネルでこれを実行しないでください。 arcfour
暗号化を使用した安全でないチャネルからのサーバーへのアクセスが心配な場合は、etc/ssh/ssh_config
をソースホストのHost-specific部分で変更します-Host
セクションを作成しますソースホストのssh_configでCiphers arcfour
を使用して上記の-c
スイッチをミラー化し、arcfour
暗号化をこのホストのみに制限できます。
詳細については、ssh_config
のマニュアルページを参照してください。
ただし、CPUがAES-NI命令セットをサポートしている場合は、aes128-gcm @ openssh.com(つまり、@を含む暗号名)に切り替えてみてください。 -GCM。
したがって、CPUがAES-NIをサポートしている場合、"ssh -T -c arcfour -o Compression=no -x"
を"ssh -T -c [email protected] -o Compression=no -x"
に変更すると、より安全な結果が得られます。
-z
は使用しないでください。非常に遅くなります)a
:アーカイブモード-再帰的、所有者を保持、権限を保持、変更時間を保持、グループを保持、シンボリックリンクをシンボリックリンクとしてコピー、デバイスファイルを保持。H
:ハードリンクを保持しますA
:ACLを保持しますX
:拡張属性を保持しますx
:ファイルシステムの境界を越えないv
:詳細度を上げる--numeric-ds
:ユーザー/グループ名でuid/gid値をマッピングしない--delete
を追加します。destディレクトリから不要なファイルを削除します(同期中の差分クリーンアップ)--progress
:転送中に進行状況を表示T
:疑似ttyをオフにして、宛先でのCPU負荷を減らします。c arcfour
:最も弱いが最速のSSH暗号化を使用します。宛先のsshd_configで「Ciphers arcfour」を指定する必要があります。o Compression=no
:SSH圧縮をオフにします。x
:デフォルトでオンになっている場合は、X転送をオフにします。牛肉はssh
オプションにあります-rsync -av
と-e ssh -T -c arcfour -o Compression=no -x"
の部分だけを使用する場合も、これらの速度を得ることができます。
rsync -az
scp -Cr
rsync -a
sftp
scp -r
sftp -R 128 -B 65536
rsync -a -P -e "ssh -T -c arcfour -o Compression=no -x"
scp -r -c arcfour
sftp -oCiphers=arcfour
出典:
https://Gist.github.com/KartikTalwar/4393116
http://nz2nz.blogspot.com/2018/05/rsync-scp-sftp-speed-test.html
私の計算によると、最速のフルコピーは常に「tar」を使用しています(ここではGNU tar
または互換性があると仮定しています)。
mkdir -p photos2 &&
tar -C photos -cf - --exclude=./.thumbcache . |
tar -C photos2 -xpf -
また、tar
には、属性、権限、ファイルの選択/除外を操作するためのオプションがたくさんあります。たとえば、上記のコマンドは、コピー中に.thumbcacheと呼ばれる最上位のサブフォルダーを除外します。