我怎麼能讓這個 Bash 變數運作: myformat="--format=fuller --date=format:%Y-%m-%d T%H"

我怎麼能讓這個 Bash 變數運作: myformat="--format=fuller --date=format:%Y-%m-%d T%H"

這是一個關於 Bash 如何處理單字分組和變數擴展的問題。我將用一個非常具體的例子來證明這個問題:

bash$ git log --format=fuller --date=format:"%Y-%m-%d T%H"    # This works.

# Sample output:
commit aba22155684
Author:     SerMetAla
AuthorDate: 2018-04-12 T23
Commit:     SerMetAla
CommitDate: 2018-04-12 T23

    Here is the commit message.

我希望這個能起作用:

bash$ git log "$myformat"    # It should print the same stuff.

我不知道如何僅用一個 Bash 變數來實現這一點。這是一個包含兩個變數的工作範例:

# Define the two variables:
bash$ mypref="--format=fuller"
bash$ mydate="--date=format:%Y-%m-%d T%H"    # Note: No " after the colon.

# Now use it:
bash$ git log "$mypref" "$mydate"    # It works.

問題是:我怎麼能只用一個 Bash 變數來完成這項工作?是否可以?

主要問題:

git log --format=fuller --date=format:"%Y-%m-%d T%H"
                       |                       ^ This space is inside one argument.
                       |
                       ^ This space separates two arguments.

我想使用普通的字串變數。我不想使用數組變量,我不想使用$'...',我不想使用函數,我不想使用別名。當字串是不可變的,並且它不在命令的開頭時,感覺它應該是一個 Bash 變數。

我可以很容易地用一個具有相當可讀性的函數來解決這個問題。我可以用其他 Bash 技巧以一種可怕的方式解決這個問題。我想使用字串變數。

答案1

我不想使用數組變量

您正在拒絕適合這項工作的工具。好吧,你可以嘗試eval

$> foo='a "b c"'
$> printf "%s\n" $foo
a
"b
c"
$> eval printf '"%s\n"' $foo
a
b c
$>

在你的情況下,它會是這樣的:

myformat='--format=fuller --date=format:"%Y-%m-%d T%H"'
eval git log $myformat

答案2

這是常見的常見問題。https://mywiki.wooledge.org/BashFAQ/050

簡而言之,解決這個問題的方法是將參數放入陣列中。

myformat=("$mypref" "$mydate")
git log "${myformat[@]}"

作為一種非常粗略的解決方法,您也可以printf與引用格式說明符一起使用:

printf -v myformat '%q %q' "$mypref" "$mydate"
git log $myformat

相關內容