次の一連のコマンドがあります。
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