Ich schreibe eine Funktion, die Daten ausgibt. Ich möchte dem Benutzer ermöglichen, die Ausgabe anzupassen, indem er Argumente date
mit 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, date
wä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 bash
Funktion würde ihre Befehlszeilenargumente durchgehen und sie im opts
Array 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 opts
wird 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 date
fü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_ARGS
lediglich 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