2

bashでscpを使用してリモートファイルをローカルシステムにコピーしようとすると、必要な
ファイル名を取得して変数に割り当てまし$lastModifiedFile
が、問題はファイル名にスペースが含まれていることです。
この変数をscpで使用するには、スペースをバックスラッシュでエスケープする必要があります。
この変数をフォーマットし、必要に応じて、つまりスペースに正しいエスケープ文字を挿入する簡単な方法はありますか?

#!/bin/bash

lastModifiedFile=$(sshpass -p 'passw0rd' ssh user@server 'ls -tr /path/output*| tail -n 1')
echo "$lastModifiedFile"

sshpass -p 'passw0rd' scp user@server:"$lastModifiedFile" /root/

これはスクリプト出力です。

[user@host ~]# ./script.sh 
/path/outputSat Mar 09 151905 GMT 2013.html
scp: /path/outputSat: No such file or directory
scp: Mar: No such file or directory
scp: 09: No such file or directory
scp: 151905: No such file or directory
scp: GMT: No such file or directory
scp: 2013.html: No such file or directory

私は以下のようなもの、またはさらに簡単な解決策を探していますか?..

escapedFilename=""

for letter in $lastModifiedFile
    if $letter == " "
        $escapedFilename += "\ "
    else
        $escapedFilename += $letter
4

4 に答える 4

1

傾いた楊症候群が少しある場合:

param=user@server:${lastModifiedFile// /\\ /}

sshpass -p 'passw0rd' scp "$param" /root/

編集:それはscp私が好きではないようです。テストでは追加のレベルの変数が必要でした...:)

編集2: OPのフィードバックによると、正確な解決策は使用することで構成されて${lastModifiedFile// /\\ \\} いるようです。他のファイル名でエスケープする必要のあるスペース以外の文字がないことを願っています:)

于 2013-03-09T17:12:37.457 に答える
1

リモートシステムに渡されるファイル名を一重引用符で囲み、単語分割の対象にならないようにします。

lastModifiedFile=$(sshpass -p 'passw0rd' ssh user@server 'ls -tr /path/output*| tail -n 1')
echo "$lastModifiedFile"

sshpass -p 'passw0rd' scp user@server:"'$lastModifiedFile'" /root/

また

sshpass -p 'passw0rd' scp "user@server:'$lastModifiedFile'" /root/
于 2013-03-10T02:33:14.647 に答える
0

このようにしてください:

sshpass -p 'passw0rd' scp 'user@server:$lastModifiedFile' /root/
于 2013-03-09T17:05:25.150 に答える
0

ファイル名のほとんどすべて(スペースだけでなく)を処理する必要があるいくつかのメソッドを次に示します。まず、bashのprintf組み込みには%q、文字列に引用符/エスケープなどを追加する形式があります。

sshpass -p 'passw0rd' scp user@server:"$(printf %q "$lastModifiedFile")" /root/

ただし、この引用符/エスケープなどは、bashによる解釈に適していることに注意してください。リモートコンピュータのデフォルトシェルが別のものである場合、これはすべての場合に機能するとは限りません。

オプション2は、原則として単純であり(ただし、実際には少し面倒です)、より多くのリモートシェルと互換性があるはずです。ここでは、ファイル名を一重引用符で囲みます。これは、ファイル名内の一重引用符以外でも機能するはずです。それらの代わりに、'\''(一重引用符で囲まれた文字列を終了し、エスケープされた一重引用符を追加してから、一重引用符で囲まれた文字列を再開します):

repl="'\''" # Have to store this in a variable to work around a bash parsing oddity
sshpass -p 'passw0rd' scp user@server:"'${lastModifiedFile//\'/$repl}'" /root/
于 2013-03-10T01:28:24.647 に答える