コマンドに引数を渡すときのエスケープ文字

コマンドに引数を渡すときのエスケープ文字

私はしばしばAndroid携帯電話を使用してオーディオファイルをWAVファイルとして携帯電話の内部ストレージに録音します。最近録音したファイルを携帯電話から抽出してデスクトップに移動するBashスクリプトを作成したいと思います。これが私が今まで得たものです:

adb shell find /storage/sdcard0/Sound\ Recordings/ | tail -1 | while read file ; do
    adb pull "$file" ~/Desktop/
done

しかし、これは失敗しました。 ADBが正しくエスケープされていないようでスクリプトを実行しようとすると、次のメッセージが表示されます。

' does not existstorage/sdcard0/Sound Recordings/20120817T065953.wav

二重引用符を無視しているように見え、実行しようとすると、次のように2つではなく3つの引数が表示される可能性があるため、デフォルトではすべてが中断されます。

adb pull /storage/sdcard0/Sound Recordings/20120817T065953.wav ~/Desktop/

$file必要に応じて、変数にバックスラッシュを挿入するようにスクリプトを調整するにはどうすればよいですか?この場合、これは正しい解決策ですか?

答え1

他のシェルレベルで実行されているため拡張されます。今後サブシェルで実行されます。この問題を解決する最も簡単な方法は、ファイル名のすべての特殊文字をエスケープすることです。

adb shell find /storage/sdcard0/Sound\ Recordings/ | tail -1 | while IFS= read -r file ; do
    adb pull "$(printf %q "$file")" ~/Desktop/
done

答え2

解決策は次のとおりです。

adb pull "/storage/sdcard0/Sound Recordings/$(
    adb shell ls -1t '/storage/sdcard0/Sound Recordings' |
        sed q |
        tr -d '\r'
)" .

adbWindowsがいくつかのキャリッジリターンを返すように問題が発生しました。\r

sed q最初の発生を示す楽しい方法です。head -n1

関連情報