SCPファイルパターンから文字を除外

SCPファイルパターンから文字を除外

scpファイルをコピーするために使用できる式を構成する方法はありますか?

file-name-version-1.2.1.jar

ファイルをコピーする必要はありません。

file-name-version-1.2.1-sources.jar
file-name-version-1.2.1-javadoc.jar

しかし、正しいバージョン番号がわからないのですか?file-name-version-*.*.*.jar明らかな理由で動作しません。私は次の構文を探しています。

file-name-version-\d.\d.\d.jar

またはそのようなもの。

ベストアンサー1

覚えておくべき1つは、ファイル名が渡されることです。変更されていないリモートユーザーのログインシェルとして。

これにより:

 scp user@remote-machine:'something' ...

リモートシステムでは、sshd次のログインシェルが実行されますuser

 that-shell -c 'scp -f something'

その中のパターンを拡張するのがまさにこの殻です。

つまり、パターン拡張方法は、リモートユーザーが使用するログインシェルによって異なります。そのシェルがある場合、bashユーザーが~/.bashrc何を持っているのか、それに何があるのか​​によって異なります/etc/bash.bashrc(たとえば、bash-completionインストール中にそこから呼び出すと、kshスタイルの拡張ワイルドカードがオンになります)。呼び出し時に何らかの理由でbashこれらの内容を読み取るためsshです(これは対話型シェルです)。

これはまた、somethingこれが真であれば'blah; rm -rf "$HOME"'悲惨な結果をもたらすことを意味します。

これは設計エラーの1つですssh

something特定のシェルを強制的にファイルのリストに拡張するには、次の方法を使用できます。

LC_SCPFILES=something scp -o SendEnv=LC_SCPFILES "localhost:</dev/null
  bash -O extglob -c 'exec scp -f -- \$LC_SCPFILES';exit" /dest/dir

リモートユーザーのログインシェルが通常のUnixシェル(少なくともBourne、csh、rc、またはFishファミリ)であり、ここにインストールされていてbash名前sshdを渡すことができる場合にのみ適用されますLC_

ヒントは、ほとんどのsshd展開では、名前が次に始まる環境変数を渡すことを許可することLC_です。これは、スペイン語を使用するユーザーがリモートシステムのデフォルト言語やリモートユーザーの言語ではなく、スペイン語のリモートコマンドからエラーメッセージを受け取るようにするために必要です。 )) 。

ここでは環境変数を渡しsomethingますLC_SCPFILES

リモートシステムで次をsshd実行します。

that-shell -c 'scp -f </dev/null
  bash -O extglob -c '\''exec scp -f -- $LC_SCPFILES'\'';exit'

/dev/null最初のものは標準入力がからリダイレクトされるのでscpすぐに終了します。次に、オプションを使用して選択したシェルを起動し、解釈にbashコマンドラインをextglob使用します。exec scp -f -- $LC_SCPFILES

サブプロセス(後で追加して強制実行)bashで実行されるため、ソースは提供されないため、デフォルトの動作が期待できます(起動時または環境変数が何らかの方法で設定されていない限り)。that-shell;exitbash~/.bashrcbashthat-shellBASHOPTSSHELLOPTSBASH_ENV

引用符がないため、$LC_SCPFILESトークン化とファイル名の生成(ワイルドカード)の影響を受けますが、他のシェル拡張の影響を受けず、埋め込まれても同様のことはrm -rf "$HOME"somethingません。

パターンがリモートシステムで拡張されていることを確認したので、拡張bash -O extglobglob演算子(ここでヘルパー関数を使用)を使用してパターンを一致させることができます。

safer_scp() (
  file=$1; shift
  export LC_SCPFILES="${file#*:}"
  exec scp -o SendEnv=LC_SCPFILES "${file%%:*}:</dev/null
    bash -O extglob -c 'exec scp -f -- \$LC_SCPFILES';exit" "$@"
)
safer_scp user@host:'file-name-version-+([0-9]).+([0-9]).+([0-9]).jar' .

on を使用すると、+([0-9])1 つ以上の小数点以下の桁数と一致します。たとえば、上記のパターンは一致します。extglobbashfile-name-version-1.2.3.jarfile-name-version-12.123.1234.jar

(上記では、safer_scp最初の引数があり、または同じものは機能しないと仮定しますhost:file-patternssafer_scp -r ...safer_scp host1:f1 host2:f2 ...-rsafer_scp_rscp -fscp -r -f

IFS=;上記の単語の区切りを追加すると、単語の区切りを無効にできますexec scp...

また、すべてのGNUシステムにインストールされているので、ここで使用していますが、リモートシステムにインストールされていることがわかっている場合は、bash次のものを使用できます。zsh

zsh -o extendedglob -o globsust

zsh代わりに、ワイルドカード(再帰、修飾子...)のすべての機能を活用してください。

-o shwordsplit単語分割も必要な場合は追加)。

たとえば、

safer_scp() (
  file=$1; shift
  export LC_SCPFILES="${file#*:}"
  exec scp -o SendEnv=LC_SCPFILES "${file%%:*}:</dev/null
    zsh -o extendedglob -o globsubst -c 'exec scp -f -- \$LC_SCPFILES';exit" "$@"
)
safer_scp user@host:'file-name-version-<->(.<->)#.jar' .

は から までの任意の 10 進整数file-name-version-1.jarであり、正規表現演算子のような任意の 10 進整数です (0 以上の先行原子)。file-name-version-1.2.3.4.5.jar<x-y>xy<->#*

おすすめ記事