値にオプションとスペースを含むパス名を含む変数を展開します。

値にオプションとスペースを含むパス名を含む変数を展開します。
$ md="-l /tmp/test/my dir"
$ ls "$md"
ls: invalid option -- ' '
Try 'ls --help' for more information.

$ md="-l \"/tmp/test/my dir\""
$ ls "$md"
ls: invalid option -- ' '
Try 'ls --help' for more information.

なぜ両方が機能しないのだろうか。ありがとうございます。変数の値には以下が含まれます。

  • オプション-l
  • スペースを含むパス名パラメータ
  • 上記の2つの項目はスペースで区切ります。

私の実際の質問は次のとおりです。スクリプトを作成しました。myscript.sh

#! /bin/bash

old_dest=""
while getopts ":l:t" opt; do
    case $opt in
        l)
            old_dest="--link-dest \"$OPTARG\""
            ;;
    esac
done

rsync -a --delete "$old_dest" /path/to/source  /path/to/dest

-lオプションを含むコマンドでスクリプトを呼び出したいです。

myscript.sh -l "/media/t/my external hdd/backup/old one"

スクリプトで割り当てられた部分はどのように書くべきですかold_dest

ベストアンサー1

コマンドが機能しない理由は、引用符/単語分割が再帰的に適用されないためです。

したがって、"$old_dest"次のSINGLEパラメータに展開されます。

--link-dest "/media/t/my external hdd/backup/old one"

変数は二重引用符で囲まれているため、これはすべてパラメータです。 (二重引用符は削除されますが、二重引用符は拡張の結果つまり、変数値の一部は削除されません。 )

反対方向に使用すると、複数の$old_dest引数が得られますが、望む方法ではありません。次の5つのパラメータが得られます。

--link-dest
"/media/t/my
external
hdd/backup/old
one"

これは、マニュアルの説明に従って変数拡張を実行してからトークン化を実行するためです。することができますいいえ変数拡張を取得し、変数の引用符を解釈します。引用符は削除されないため、最終引数は4文字になりますone"

他の答えで述べたように、正しい方法はBash配列を使用することです。


また、Tclが引用符と単語の区切り文字を処理する方法が好きかもしれません。シェルトークン化には非常に慣れていますが、より直感的かもしれませんが、シェルよりもTclについてもっと考える必要があります。

おすすめ記事