ディレクトリにスペースを許可するには、このコードスニペットをどのように適切に処理する必要がありますか?

ディレクトリにスペースを許可するには、このコードスニペットをどのように適切に処理する必要がありますか?

次の一連のコマンドがあります。

ssh -i key 10.10.10.10 mkdir -p "${DEST_PATH}/subdir1" "${DEST_PATH}/subdir2"
rsync "${SOURCE_PATH}" "$DEST_HOST:${DEST_PATH}/subdir1"
...

これらの供給変数は

DEST_PATH=$( myfun "foo" )
SOURCE_PATH=$( myfun "bar" )

これは順番に文字列を供給します。

function myfun {
  local VALUE=$( grep "$1" yadayada.txt | tail -1 | sed 's/someregex//' )
  echo "$VALUE"
}

$VALUEスペースがあれば$VALUE何をしますかHello World?私はいつもそれを使用するとすべての""問題が解決されると思いましたが、私の考えは間違っていました。他のいくつかの質問では、一重引用符を避けるか使用することを提案していますが、最良のアプローチが何であるかはよくわかりません。

ありがとう

ベストアンサー1

xargsリモートシステムに特定のオプションをサポートするコマンドがあることがわかっている場合は、-0次のことができます。

printf '%s\0' "$DEST_PATH/subdir1" "$DEST_PATH/subdir2" |
  ssh -i key 10.10.10.10 'xargs -0 mkdir -p --'

すべてのシェルはxargs -0 mkdir -p --このシェルコードを同じように解釈します(sshdリモートユーザーのログインシェルは、指定されたコードを解釈するためにリモートシステムで実行されていることに注意してくださいssh)。

mkdirリモートシェルのstdinを介して渡される引数のリストはNULで区切られますxargs

この方法のもう1つの利点は、必要な数のパラメータを渡すことができることです。必要にxargs応じてリストが破損し、パラメータmkdir -p -- dirn dirn+1...+環境リストのサイズ制限を回避するために複数の呼び出しが実行され、非常に大きなリストの完全なリストが送信される前にディレクトリの作成を開始することもできます。

バラよりリモートユーザーのログインシェルを知らず、SSHを介して任意の単純なコマンドをどのように実行できますか?他の方法の場合。

rsyncデフォルトでは、同期のためにリモートシェルコマンドラインの一部としてリモートファイル/ディレクトリ名を渡すため、それ自体同じ問題があります。より良い解決策は、シェルコードからファイル/ディレクトリ名を渡す代わりに-s/を使用することです。--protect-args、代わりにrsyncサーバーの標準入力に渡してください。

だから:

rsync -s -- "$SOURCE_PATH" "$DEST_HOST:$DEST_PATH/subdir1/"

マニュアルrsyncページを引用すると、次のようになります。

スペースを含むファイル名を転送する必要がある場合、またはリモートシェルが理解するようにスペースをエスケープする必要がある場合は--protect-args()オプションを指定できます。-sたとえば、

     rsync -av host:'file\ name\ with\ spaces' /dest
$ rsync --rsync-path='set -x; rsync' /etc/issue localhost:'1 2'
+zsh:1> rsync --server -e.LsfxC . 1 2
$ rsync --rsync-path='set -x; rsync' /etc/issue localhost:'1;uname>&2'
+zsh:1> rsync --server -e.LsfxC . 1
+zsh:1> uname
Linux

ファイル名がシェルコードとしてどのように解釈されるかを確認してください。

そして-s

~$ rsync -s --rsync-path='set -x; rsync' /etc/issue localhost:'1;uname>&2'
+zsh:1> rsync --server -se.LsfxC

リモートシェルコマンドラインにはファイル名のトレースはありません。

~$ cat '1;uname>&2'
Ubuntu 20.04.1 LTS \n \l

おすすめ記事