Kann ich den Typ einer Bash-Variablen untersuchen?

Kann ich den Typ einer Bash-Variablen untersuchen?

Ich schreibe eine Funktion, die Daten ausgibt. Ich möchte dem Benutzer ermöglichen, die Ausgabe anzupassen, indem er Argumente datemit einer Umgebungsvariable angibt. Um Leerzeichen in Formatzeichenfolgen zu erhalten, möchte ich Argumente in einem Array wie diesem akzeptieren:

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

Der Benutzer möchte möglicherweise ein Array verwenden, wenn eine Datumsformatzeichenfolge Leerzeichen enthält:

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

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

In diesem Fall wäre ein Array jedoch möglicherweise übertrieben:

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

Für einfache Fälle wie diesen möchte ich kein Array benötigen. Kann man den Typ der Variable ermitteln?

Antwort1

Mir scheint, dass Sie Ihre Funktion alle Befehlszeilenoptionen direkt an GNU weitergeben lassen möchten, datewährend Sie numerische Nicht-Optionen speziell behandeln:

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 -
}

Diese bashFunktion würde ihre Befehlszeilenargumente durchgehen und sie im optsArray speichern, bis sie auf ein Argument stößt, das ist --(die Standardmethode, um das Ende von Optionen anzuzeigen) oder das mit einer Ziffer beginnt. Jedes in gespeicherte Argument optswird aus der Liste der Befehlszeilenargumente verschoben.

Sobald ein Argument gefunden wurde, das keine Option für ist date, nehmen wir an, dass die restlichen Argumente UNIX-Epochenzeitstempel sind, und durchlaufen diese, wobei wir datefür jeden Zeitstempel unsere gespeicherten Optionen aufrufen. Lesen Sie den Kommentar im Code, um zu erfahren, wie Sie diese Schleife effizienter gestalten können.

Beispielaufrufe:

$ 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

Antwort2

Dies lässt sich wesentlich einfacher erreichen, indem Sie auf die Verwendung von Arrays verzichten und den Benutzer DATE_ARGSlediglich die Angabe einer Zeichenfolge erlauben, die in die Befehlszeile eingefügt werden soll 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

verwandte Informationen