我可以內省 bash 變數的類型嗎?

我可以內省 bash 變數的類型嗎?

我正在編寫一個輸出日期的函數。我想允許用戶透過提供date環境變數的參數來自訂輸出。為了保留格式字串中的空格,我想接受數組中的 args,如下所示:

function argdates {
    while [ $# -gt 0 ] && date "${DATE_ARGS[@]}" -d @$1
    do shift
    done
}

如果使用者在日期格式字串中包含空格,則可能需要使用陣列:

DATE_ARGS=( -u "+%y/%U, %I%p %a" )
argdates 1476395008 1493172224

# output:
# 16/41, 09PM Thu
# 17/17, 02AM Wed

但在這種情況下,數組可能有點大材小用:

DATE_ARGS="-u -Iseconds"
argdates 1476395008 1493172224

# output:
# date: invalid option -- ' '
# Try 'date --help' for more information.

# output should be:
# 2016-10-13T21:43:28+00:00
# 2017-04-26T02:03:44+00:00

對於像這樣的簡單情況,我不想需要一個陣列。是否可以判斷變數是什麼類型?

答案1

在我看來,你可能想讓你的函數將任何命令列選項直接傳遞給 GNU,date同時特別處理數字非選項:

argdates () {
    local -a opts
    local timestamp

    while [ "$#" -gt 0 ] && [ "$1" != '--' ] && [[ "$1" != [0-9]* ]]; do
        opts+=( "$1" )
        shift
    done
    [ "$1" = '--' ] && shift

    for timestamp do
        date "${opts[@]}" -d "@$timestamp"
    done

    # or, with a single invocation of "date":
    # printf '@%s\n' "$@" | date "${opts[@]}" -f -
}

bash函數將遍歷其命令列參數並將它們保存在陣列中opts,直到它遇到一個參數--(表示選項結束的標準方式)或以數字開頭的參數。保存到的每個參數opts都會從命令列參數清單中移出。

一旦發現一個參數不是 的選項date,我們就假設其餘參數是 UNIX 紀元時間戳記並循環這些,並使用date我們為每個時間戳記保存的選項進行呼叫。有關如何更有效地執行此循環的信息,請參閱程式碼中的註釋。

呼叫範例:

$ argdates 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017
$ argdates -- 1476395008 1493172224
Thu Oct 13 23:43:28 CEST 2016
Wed Apr 26 04:03:44 CEST 2017
$ argdates +%D 1476395008 1493172224
10/13/16
04/26/17
$ argdates +%F 1476395008 1493172224
2016-10-13
2017-04-26
$ argdates -u 1476395008 1493172224
Thu Oct 13 21:43:28 UTC 2016
Wed Apr 26 02:03:44 UTC 2017
$ argdates -u -Iseconds 1476395008 1493172224
2016-10-13T21:43:28+00:00
2017-04-26T02:03:44+00:00

答案2

您可以透過放棄使用陣列並讓使用者DATE_ARGS簡單地指定為應插入命令列中的字串來更輕鬆地做到這一點date

$ argdates(){
    for d; do printf %s "$DATE_ARGS" | xargs date -d "@$d"; done
}
$ DATE_ARGS='-u "+%y/%U, %I%p %a"' argdates 1476395008 1493172224
16/41, 09PM Thu
17/17, 02AM Wed
$ DATE_ARGS='-u -Iseconds' argdates 1476395008 1493172224
2016-10-13T21:43:28+00:00
2017-04-26T02:03:44+00:00

相關內容